Merge pull request #10436 from filecoin-project/jen/v1202
chore: build: v1.20.2 prep
This commit is contained in:
commit
a1f912c71d
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,5 +1,19 @@
|
|||||||
# Lotus changelog
|
# Lotus changelog
|
||||||
|
|
||||||
|
# v1.20.2 / 2023-03-09
|
||||||
|
|
||||||
|
This is a HIGHLY RECOMMENDED patch release for node operators/API service providers that run ETH RPC service and an optional release for Storage Providers.
|
||||||
|
|
||||||
|
## Bug fixes
|
||||||
|
- fix: EthAPI: use StateCompute for feeHistory; apply minimum gas premium #10413
|
||||||
|
- fix: eth API: return correct txIdx around null blocks #10419
|
||||||
|
- fix: Eth API: make block parameter parsing sounder. #10427
|
||||||
|
|
||||||
|
## Improvement
|
||||||
|
- feat: Lotus Gateway: Add missing methods - master #10420
|
||||||
|
- feat: mempool: Reduce minimum replace fee from 1.25x to 1.1x #10416
|
||||||
|
- We recommend storage providers to update your nodes to this patch, that will help improve developers who use Ethereum tooling's experience.
|
||||||
|
|
||||||
# v1.20.1 / 2023-03-06
|
# v1.20.1 / 2023-03-06
|
||||||
|
|
||||||
This an optional patch releases for node operators/API service providers that run ETH RPC service.
|
This an optional patch releases for node operators/API service providers that run ETH RPC service.
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MODIFYING THE API INTERFACE
|
// MODIFYING THE API INTERFACE
|
||||||
@ -47,15 +48,18 @@ type Gateway interface {
|
|||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||||
|
MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error)
|
||||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error)
|
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*MsigTransaction, error)
|
||||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MsigVesting, error)
|
MsigGetVestingSchedule(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MsigVesting, error)
|
||||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
|
StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*InvocResult, error)
|
||||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (DealCollateralBounds, error)
|
||||||
|
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||||
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error) //perm:read
|
StateReadState(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*ActorState, error)
|
||||||
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
||||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error)
|
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (MarketBalance, error)
|
||||||
@ -63,6 +67,7 @@ type Gateway interface {
|
|||||||
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (MinerInfo, error)
|
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (MinerInfo, error)
|
||||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error)
|
||||||
|
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error)
|
StateNetworkVersion(context.Context, types.TipSetKey) (apitypes.NetworkVersion, error)
|
||||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||||
|
@ -401,6 +401,10 @@ func init() {
|
|||||||
FromBlock: pstring("2301220"),
|
FromBlock: pstring("2301220"),
|
||||||
Address: []ethtypes.EthAddress{ethaddr},
|
Address: []ethtypes.EthAddress{ethaddr},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
percent := types.Percent(123)
|
||||||
|
addExample(percent)
|
||||||
|
addExample(&percent)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
|
||||||
|
@ -720,6 +720,8 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
||||||
|
|
||||||
|
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) ``
|
||||||
|
|
||||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
||||||
|
|
||||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
||||||
@ -736,8 +738,12 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||||
|
|
||||||
|
StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) ``
|
||||||
|
|
||||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) ``
|
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) ``
|
||||||
|
|
||||||
|
StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) ``
|
||||||
|
|
||||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
||||||
|
|
||||||
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) ``
|
StateListMiners func(p0 context.Context, p1 types.TipSetKey) ([]address.Address, error) ``
|
||||||
@ -754,9 +760,11 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
||||||
|
|
||||||
|
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) ``
|
||||||
|
|
||||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) ``
|
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) ``
|
||||||
|
|
||||||
StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) `perm:"read"`
|
StateReadState func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*ActorState, error) ``
|
||||||
|
|
||||||
StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
|
StateSearchMsg func(p0 context.Context, p1 types.TipSetKey, p2 cid.Cid, p3 abi.ChainEpoch, p4 bool) (*MsgLookup, error) ``
|
||||||
|
|
||||||
@ -4563,6 +4571,17 @@ func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Messag
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||||
|
if s.Internal.MpoolGetNonce == nil {
|
||||||
|
return 0, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.MpoolGetNonce(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||||
|
return 0, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) {
|
func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) {
|
||||||
if s.Internal.MpoolPush == nil {
|
if s.Internal.MpoolPush == nil {
|
||||||
return *new(cid.Cid), ErrNotSupported
|
return *new(cid.Cid), ErrNotSupported
|
||||||
@ -4651,6 +4670,17 @@ func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2
|
|||||||
return *new(address.Address), ErrNotSupported
|
return *new(address.Address), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) {
|
||||||
|
if s.Internal.StateCall == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateCall(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*InvocResult, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) {
|
func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) {
|
||||||
if s.Internal.StateDealProviderCollateralBounds == nil {
|
if s.Internal.StateDealProviderCollateralBounds == nil {
|
||||||
return *new(DealCollateralBounds), ErrNotSupported
|
return *new(DealCollateralBounds), ErrNotSupported
|
||||||
@ -4662,6 +4692,17 @@ func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 a
|
|||||||
return *new(DealCollateralBounds), ErrNotSupported
|
return *new(DealCollateralBounds), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) {
|
||||||
|
if s.Internal.StateDecodeParams == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) {
|
func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) {
|
||||||
if s.Internal.StateGetActor == nil {
|
if s.Internal.StateGetActor == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
@ -4750,6 +4791,17 @@ func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.A
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
|
||||||
|
if s.Internal.StateNetworkName == nil {
|
||||||
|
return *new(dtypes.NetworkName), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateNetworkName(p0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
|
||||||
|
return *new(dtypes.NetworkName), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) {
|
func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (apitypes.NetworkVersion, error) {
|
||||||
if s.Internal.StateNetworkVersion == nil {
|
if s.Internal.StateNetworkVersion == nil {
|
||||||
return *new(apitypes.NetworkVersion), ErrNotSupported
|
return *new(apitypes.NetworkVersion), ErrNotSupported
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MODIFYING THE API INTERFACE
|
// MODIFYING THE API INTERFACE
|
||||||
@ -44,12 +45,15 @@ type Gateway interface {
|
|||||||
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
|
ChainNotify(context.Context) (<-chan []*api.HeadChange, error)
|
||||||
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
ChainReadObj(context.Context, cid.Cid) ([]byte, error)
|
||||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||||
|
MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error)
|
||||||
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, error)
|
MsigGetPending(context.Context, address.Address, types.TipSetKey) ([]*api.MsigTransaction, error)
|
||||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
|
StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error)
|
||||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
|
||||||
|
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||||
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
StateGetReceipt(context.Context, cid.Cid, types.TipSetKey) (*types.MessageReceipt, error)
|
||||||
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
||||||
@ -59,6 +63,7 @@ type Gateway interface {
|
|||||||
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error)
|
StateMinerInfo(ctx context.Context, actor address.Address, tsk types.TipSetKey) (api.MinerInfo, error)
|
||||||
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error)
|
||||||
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
|
StateMinerPower(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error)
|
||||||
|
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (abinetwork.Version, error)
|
StateNetworkVersion(context.Context, types.TipSetKey) (abinetwork.Version, error)
|
||||||
StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error)
|
StateSearchMsg(ctx context.Context, msg cid.Cid) (*api.MsgLookup, error)
|
||||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||||
|
@ -451,6 +451,8 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *api.MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
|
||||||
|
|
||||||
|
MpoolGetNonce func(p0 context.Context, p1 address.Address) (uint64, error) ``
|
||||||
|
|
||||||
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
|
||||||
|
|
||||||
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
MsigGetAvailableBalance func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (types.BigInt, error) ``
|
||||||
@ -461,8 +463,12 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
|
||||||
|
|
||||||
|
StateCall func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) ``
|
||||||
|
|
||||||
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) ``
|
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) ``
|
||||||
|
|
||||||
|
StateDecodeParams func(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) ``
|
||||||
|
|
||||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) ``
|
||||||
|
|
||||||
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) ``
|
StateGetReceipt func(p0 context.Context, p1 cid.Cid, p2 types.TipSetKey) (*types.MessageReceipt, error) ``
|
||||||
@ -481,6 +487,8 @@ type GatewayMethods struct {
|
|||||||
|
|
||||||
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
StateMinerProvingDeadline func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*dline.Info, error) ``
|
||||||
|
|
||||||
|
StateNetworkName func(p0 context.Context) (dtypes.NetworkName, error) ``
|
||||||
|
|
||||||
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) ``
|
StateNetworkVersion func(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) ``
|
||||||
|
|
||||||
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) ``
|
StateSearchMsg func(p0 context.Context, p1 cid.Cid) (*api.MsgLookup, error) ``
|
||||||
@ -2677,6 +2685,17 @@ func (s *GatewayStub) GasEstimateMessageGas(p0 context.Context, p1 *types.Messag
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||||
|
if s.Internal.MpoolGetNonce == nil {
|
||||||
|
return 0, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.MpoolGetNonce(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) MpoolGetNonce(p0 context.Context, p1 address.Address) (uint64, error) {
|
||||||
|
return 0, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) {
|
func (s *GatewayStruct) MpoolPush(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) {
|
||||||
if s.Internal.MpoolPush == nil {
|
if s.Internal.MpoolPush == nil {
|
||||||
return *new(cid.Cid), ErrNotSupported
|
return *new(cid.Cid), ErrNotSupported
|
||||||
@ -2732,6 +2751,17 @@ func (s *GatewayStub) StateAccountKey(p0 context.Context, p1 address.Address, p2
|
|||||||
return *new(address.Address), ErrNotSupported
|
return *new(address.Address), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) {
|
||||||
|
if s.Internal.StateCall == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateCall(p0, p1, p2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateCall(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (*api.InvocResult, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) {
|
func (s *GatewayStruct) StateDealProviderCollateralBounds(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (api.DealCollateralBounds, error) {
|
||||||
if s.Internal.StateDealProviderCollateralBounds == nil {
|
if s.Internal.StateDealProviderCollateralBounds == nil {
|
||||||
return *new(api.DealCollateralBounds), ErrNotSupported
|
return *new(api.DealCollateralBounds), ErrNotSupported
|
||||||
@ -2743,6 +2773,17 @@ func (s *GatewayStub) StateDealProviderCollateralBounds(p0 context.Context, p1 a
|
|||||||
return *new(api.DealCollateralBounds), ErrNotSupported
|
return *new(api.DealCollateralBounds), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) {
|
||||||
|
if s.Internal.StateDecodeParams == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateDecodeParams(p0, p1, p2, p3, p4)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateDecodeParams(p0 context.Context, p1 address.Address, p2 abi.MethodNum, p3 []byte, p4 types.TipSetKey) (interface{}, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) {
|
func (s *GatewayStruct) StateGetActor(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) {
|
||||||
if s.Internal.StateGetActor == nil {
|
if s.Internal.StateGetActor == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
@ -2842,6 +2883,17 @@ func (s *GatewayStub) StateMinerProvingDeadline(p0 context.Context, p1 address.A
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStruct) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
|
||||||
|
if s.Internal.StateNetworkName == nil {
|
||||||
|
return *new(dtypes.NetworkName), ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateNetworkName(p0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *GatewayStub) StateNetworkName(p0 context.Context) (dtypes.NetworkName, error) {
|
||||||
|
return *new(dtypes.NetworkName), ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) {
|
func (s *GatewayStruct) StateNetworkVersion(p0 context.Context, p1 types.TipSetKey) (abinetwork.Version, error) {
|
||||||
if s.Internal.StateNetworkVersion == nil {
|
if s.Internal.StateNetworkVersion == nil {
|
||||||
return *new(abinetwork.Version), ErrNotSupported
|
return *new(abinetwork.Version), ErrNotSupported
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -37,7 +37,7 @@ func BuildTypeString() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// BuildVersion is the local build version
|
// BuildVersion is the local build version
|
||||||
const BuildVersion = "1.20.1"
|
const BuildVersion = "1.20.2"
|
||||||
|
|
||||||
func UserVersion() string {
|
func UserVersion() string {
|
||||||
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
if os.Getenv("LOTUS_VERSION_IGNORE_COMMIT") == "1" {
|
||||||
|
@ -13,7 +13,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ReplaceByFeeRatioDefault = 1.25
|
ReplaceByFeePercentageMinimum types.Percent = 110
|
||||||
|
ReplaceByFeePercentageDefault types.Percent = 125
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
MemPoolSizeLimitHiDefault = 30000
|
MemPoolSizeLimitHiDefault = 30000
|
||||||
MemPoolSizeLimitLoDefault = 20000
|
MemPoolSizeLimitLoDefault = 20000
|
||||||
PruneCooldownDefault = time.Minute
|
PruneCooldownDefault = time.Minute
|
||||||
@ -60,9 +64,9 @@ func (mp *MessagePool) getConfig() *types.MpoolConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validateConfg(cfg *types.MpoolConfig) error {
|
func validateConfg(cfg *types.MpoolConfig) error {
|
||||||
if cfg.ReplaceByFeeRatio < ReplaceByFeeRatioDefault {
|
if cfg.ReplaceByFeeRatio < ReplaceByFeePercentageMinimum {
|
||||||
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %f < %f",
|
return fmt.Errorf("'ReplaceByFeeRatio' is less than required %s < %s",
|
||||||
cfg.ReplaceByFeeRatio, ReplaceByFeeRatioDefault)
|
cfg.ReplaceByFeeRatio, ReplaceByFeePercentageMinimum)
|
||||||
}
|
}
|
||||||
if cfg.GasLimitOverestimation < 1 {
|
if cfg.GasLimitOverestimation < 1 {
|
||||||
return fmt.Errorf("'GasLimitOverestimation' cannot be less than 1")
|
return fmt.Errorf("'GasLimitOverestimation' cannot be less than 1")
|
||||||
@ -91,7 +95,7 @@ func DefaultConfig() *types.MpoolConfig {
|
|||||||
return &types.MpoolConfig{
|
return &types.MpoolConfig{
|
||||||
SizeLimitHigh: MemPoolSizeLimitHiDefault,
|
SizeLimitHigh: MemPoolSizeLimitHiDefault,
|
||||||
SizeLimitLow: MemPoolSizeLimitLoDefault,
|
SizeLimitLow: MemPoolSizeLimitLoDefault,
|
||||||
ReplaceByFeeRatio: ReplaceByFeeRatioDefault,
|
ReplaceByFeeRatio: ReplaceByFeePercentageDefault,
|
||||||
PruneCooldown: PruneCooldownDefault,
|
PruneCooldown: PruneCooldownDefault,
|
||||||
GasLimitOverestimation: GasLimitOverestimation,
|
GasLimitOverestimation: GasLimitOverestimation,
|
||||||
}
|
}
|
||||||
|
@ -48,10 +48,8 @@ var log = logging.Logger("messagepool")
|
|||||||
|
|
||||||
var futureDebug = false
|
var futureDebug = false
|
||||||
|
|
||||||
var rbfNumBig = types.NewInt(uint64((ReplaceByFeeRatioDefault - 1) * RbfDenom))
|
var rbfNumBig = types.NewInt(uint64(ReplaceByFeePercentageMinimum))
|
||||||
var rbfDenomBig = types.NewInt(RbfDenom)
|
var rbfDenomBig = types.NewInt(100)
|
||||||
|
|
||||||
const RbfDenom = 256
|
|
||||||
|
|
||||||
var RepublishInterval = time.Duration(10*build.BlockDelaySecs+build.PropagationDelaySecs) * time.Second
|
var RepublishInterval = time.Duration(10*build.BlockDelaySecs+build.PropagationDelaySecs) * time.Second
|
||||||
|
|
||||||
@ -198,7 +196,13 @@ func newMsgSet(nonce uint64) *msgSet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
|
func ComputeMinRBF(curPrem abi.TokenAmount) abi.TokenAmount {
|
||||||
minPrice := types.BigAdd(curPrem, types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig))
|
minPrice := types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig)
|
||||||
|
return types.BigAdd(minPrice, types.NewInt(1))
|
||||||
|
}
|
||||||
|
|
||||||
|
func ComputeRBF(curPrem abi.TokenAmount, replaceByFeeRatio types.Percent) abi.TokenAmount {
|
||||||
|
rbfNumBig := types.NewInt(uint64(replaceByFeeRatio))
|
||||||
|
minPrice := types.BigDiv(types.BigMul(curPrem, rbfNumBig), rbfDenomBig)
|
||||||
return types.BigAdd(minPrice, types.NewInt(1))
|
return types.BigAdd(minPrice, types.NewInt(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ type MpoolConfig struct {
|
|||||||
PriorityAddrs []address.Address
|
PriorityAddrs []address.Address
|
||||||
SizeLimitHigh int
|
SizeLimitHigh int
|
||||||
SizeLimitLow int
|
SizeLimitLow int
|
||||||
ReplaceByFeeRatio float64
|
ReplaceByFeeRatio Percent
|
||||||
PruneCooldown time.Duration
|
PruneCooldown time.Duration
|
||||||
GasLimitOverestimation float64
|
GasLimitOverestimation float64
|
||||||
}
|
}
|
||||||
|
39
chain/types/percent.go
Normal file
39
chain/types/percent.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Percent stores a signed percentage as an int64. When converted to a string (or json), it's stored
|
||||||
|
// as a decimal with two places (e.g., 100% -> 1.00).
|
||||||
|
type Percent int64
|
||||||
|
|
||||||
|
func (p Percent) String() string {
|
||||||
|
abs := p
|
||||||
|
sign := ""
|
||||||
|
if abs < 0 {
|
||||||
|
abs = -abs
|
||||||
|
sign = "-"
|
||||||
|
}
|
||||||
|
return fmt.Sprintf(`%s%d.%d`, sign, abs/100, abs%100)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p Percent) MarshalJSON() ([]byte, error) {
|
||||||
|
return []byte(p.String()), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Percent) UnmarshalJSON(b []byte) error {
|
||||||
|
flt, err := strconv.ParseFloat(string(b)+"e2", 64)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("unable to parse ratio %s: %w", string(b), err)
|
||||||
|
}
|
||||||
|
if math.Trunc(flt) != flt {
|
||||||
|
return xerrors.Errorf("ratio may only have two decimals: %s", string(b))
|
||||||
|
}
|
||||||
|
*p = Percent(flt)
|
||||||
|
return nil
|
||||||
|
}
|
34
chain/types/percent_test.go
Normal file
34
chain/types/percent_test.go
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestPercent(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
p Percent
|
||||||
|
s string
|
||||||
|
}{
|
||||||
|
{100, "1.0"},
|
||||||
|
{111, "1.11"},
|
||||||
|
{12, "0.12"},
|
||||||
|
{-12, "-0.12"},
|
||||||
|
{1012, "10.12"},
|
||||||
|
{-1012, "-10.12"},
|
||||||
|
{0, "0.0"},
|
||||||
|
} {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("%d <> %s", tc.p, tc.s), func(t *testing.T) {
|
||||||
|
m, err := tc.p.MarshalJSON()
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Equal(t, tc.s, string(m))
|
||||||
|
var p Percent
|
||||||
|
require.NoError(t, p.UnmarshalJSON([]byte(tc.s)))
|
||||||
|
require.Equal(t, tc.p, p)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -461,7 +461,12 @@ var MpoolReplaceCmd = &cli.Command{
|
|||||||
msg := found.Message
|
msg := found.Message
|
||||||
|
|
||||||
if cctx.Bool("auto") {
|
if cctx.Bool("auto") {
|
||||||
minRBF := messagepool.ComputeMinRBF(msg.GasPremium)
|
cfg, err := api.MpoolGetConfig(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return xerrors.Errorf("failed to lookup the message pool config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultRBF := messagepool.ComputeRBF(msg.GasPremium, cfg.ReplaceByFeeRatio)
|
||||||
|
|
||||||
var mss *lapi.MessageSendSpec
|
var mss *lapi.MessageSendSpec
|
||||||
if cctx.IsSet("fee-limit") {
|
if cctx.IsSet("fee-limit") {
|
||||||
@ -482,7 +487,7 @@ var MpoolReplaceCmd = &cli.Command{
|
|||||||
return xerrors.Errorf("failed to estimate gas values: %w", err)
|
return xerrors.Errorf("failed to estimate gas values: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.GasPremium = big.Max(retm.GasPremium, minRBF)
|
msg.GasPremium = big.Max(retm.GasPremium, defaultRBF)
|
||||||
msg.GasFeeCap = big.Max(retm.GasFeeCap, msg.GasPremium)
|
msg.GasFeeCap = big.Max(retm.GasFeeCap, msg.GasPremium)
|
||||||
|
|
||||||
mff := func() (abi.TokenAmount, error) {
|
mff := func() (abi.TokenAmount, error) {
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/filecoin-project/go-state-types/big"
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/mock"
|
"github.com/filecoin-project/lotus/chain/types/mock"
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
@ -298,6 +299,7 @@ func TestReplace(t *testing.T) {
|
|||||||
mockApi.EXPECT().ChainGetMessage(ctx, sm.Cid()).Return(&sm.Message, nil),
|
mockApi.EXPECT().ChainGetMessage(ctx, sm.Cid()).Return(&sm.Message, nil),
|
||||||
mockApi.EXPECT().ChainHead(ctx).Return(nil, nil),
|
mockApi.EXPECT().ChainHead(ctx).Return(nil, nil),
|
||||||
mockApi.EXPECT().MpoolPending(ctx, types.EmptyTSK).Return([]*types.SignedMessage{sm}, nil),
|
mockApi.EXPECT().MpoolPending(ctx, types.EmptyTSK).Return([]*types.SignedMessage{sm}, nil),
|
||||||
|
mockApi.EXPECT().MpoolGetConfig(ctx).Return(messagepool.DefaultConfig(), nil),
|
||||||
// use gomock.any to match the message in expected api calls
|
// use gomock.any to match the message in expected api calls
|
||||||
// since the replace function modifies the message between calls, it would be pointless to try to match the exact argument
|
// since the replace function modifies the message between calls, it would be pointless to try to match the exact argument
|
||||||
mockApi.EXPECT().GasEstimateMessageGas(ctx, gomock.Any(), &mss, types.EmptyTSK).Return(&sm.Message, nil),
|
mockApi.EXPECT().GasEstimateMessageGas(ctx, gomock.Any(), &mss, types.EmptyTSK).Return(&sm.Message, nil),
|
||||||
@ -342,6 +344,7 @@ func TestReplace(t *testing.T) {
|
|||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
mockApi.EXPECT().ChainHead(ctx).Return(nil, nil),
|
mockApi.EXPECT().ChainHead(ctx).Return(nil, nil),
|
||||||
mockApi.EXPECT().MpoolPending(ctx, types.EmptyTSK).Return([]*types.SignedMessage{sm}, nil),
|
mockApi.EXPECT().MpoolPending(ctx, types.EmptyTSK).Return([]*types.SignedMessage{sm}, nil),
|
||||||
|
mockApi.EXPECT().MpoolGetConfig(ctx).Return(messagepool.DefaultConfig(), nil),
|
||||||
// use gomock.any to match the message in expected api calls
|
// use gomock.any to match the message in expected api calls
|
||||||
// since the replace function modifies the message between calls, it would be pointless to try to match the exact argument
|
// since the replace function modifies the message between calls, it would be pointless to try to match the exact argument
|
||||||
mockApi.EXPECT().GasEstimateMessageGas(ctx, gomock.Any(), &mss, types.EmptyTSK).Return(&sm.Message, nil),
|
mockApi.EXPECT().GasEstimateMessageGas(ctx, gomock.Any(), &mss, types.EmptyTSK).Return(&sm.Message, nil),
|
||||||
@ -538,7 +541,7 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mpoolCfg := &types.MpoolConfig{PriorityAddrs: []address.Address{senderAddr}, SizeLimitHigh: 1234567, SizeLimitLow: 6, ReplaceByFeeRatio: 0.25}
|
mpoolCfg := &types.MpoolConfig{PriorityAddrs: []address.Address{senderAddr}, SizeLimitHigh: 1234567, SizeLimitLow: 6, ReplaceByFeeRatio: types.Percent(25)}
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
mockApi.EXPECT().MpoolGetConfig(ctx).Return(mpoolCfg, nil),
|
mockApi.EXPECT().MpoolGetConfig(ctx).Return(mpoolCfg, nil),
|
||||||
)
|
)
|
||||||
@ -566,7 +569,7 @@ func TestConfig(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
mpoolCfg := &types.MpoolConfig{PriorityAddrs: []address.Address{senderAddr}, SizeLimitHigh: 234567, SizeLimitLow: 3, ReplaceByFeeRatio: 0.33}
|
mpoolCfg := &types.MpoolConfig{PriorityAddrs: []address.Address{senderAddr}, SizeLimitHigh: 234567, SizeLimitLow: 3, ReplaceByFeeRatio: types.Percent(33)}
|
||||||
gomock.InOrder(
|
gomock.InOrder(
|
||||||
mockApi.EXPECT().MpoolSetConfig(ctx, mpoolCfg).Return(nil),
|
mockApi.EXPECT().MpoolSetConfig(ctx, mpoolCfg).Return(nil),
|
||||||
)
|
)
|
||||||
|
@ -2879,7 +2879,7 @@ Response:
|
|||||||
],
|
],
|
||||||
"SizeLimitHigh": 123,
|
"SizeLimitHigh": 123,
|
||||||
"SizeLimitLow": 123,
|
"SizeLimitLow": 123,
|
||||||
"ReplaceByFeeRatio": 12.3,
|
"ReplaceByFeeRatio": 1.23,
|
||||||
"PruneCooldown": 60000000000,
|
"PruneCooldown": 60000000000,
|
||||||
"GasLimitOverestimation": 12.3
|
"GasLimitOverestimation": 12.3
|
||||||
}
|
}
|
||||||
@ -3167,7 +3167,7 @@ Inputs:
|
|||||||
],
|
],
|
||||||
"SizeLimitHigh": 123,
|
"SizeLimitHigh": 123,
|
||||||
"SizeLimitLow": 123,
|
"SizeLimitLow": 123,
|
||||||
"ReplaceByFeeRatio": 12.3,
|
"ReplaceByFeeRatio": 1.23,
|
||||||
"PruneCooldown": 60000000000,
|
"PruneCooldown": 60000000000,
|
||||||
"GasLimitOverestimation": 12.3
|
"GasLimitOverestimation": 12.3
|
||||||
}
|
}
|
||||||
|
@ -3816,7 +3816,7 @@ Response:
|
|||||||
],
|
],
|
||||||
"SizeLimitHigh": 123,
|
"SizeLimitHigh": 123,
|
||||||
"SizeLimitLow": 123,
|
"SizeLimitLow": 123,
|
||||||
"ReplaceByFeeRatio": 12.3,
|
"ReplaceByFeeRatio": 1.23,
|
||||||
"PruneCooldown": 60000000000,
|
"PruneCooldown": 60000000000,
|
||||||
"GasLimitOverestimation": 12.3
|
"GasLimitOverestimation": 12.3
|
||||||
}
|
}
|
||||||
@ -4104,7 +4104,7 @@ Inputs:
|
|||||||
],
|
],
|
||||||
"SizeLimitHigh": 123,
|
"SizeLimitHigh": 123,
|
||||||
"SizeLimitLow": 123,
|
"SizeLimitLow": 123,
|
||||||
"ReplaceByFeeRatio": 12.3,
|
"ReplaceByFeeRatio": 1.23,
|
||||||
"PruneCooldown": 60000000000,
|
"PruneCooldown": 60000000000,
|
||||||
"GasLimitOverestimation": 12.3
|
"GasLimitOverestimation": 12.3
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ USAGE:
|
|||||||
lotus-miner [global options] command [command options] [arguments...]
|
lotus-miner [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
1.20.1
|
1.20.2
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
init Initialize a lotus miner repo
|
init Initialize a lotus miner repo
|
||||||
|
@ -7,7 +7,7 @@ USAGE:
|
|||||||
lotus-worker [global options] command [command options] [arguments...]
|
lotus-worker [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
1.20.1
|
1.20.2
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
run Start lotus worker
|
run Start lotus worker
|
||||||
|
@ -7,7 +7,7 @@ USAGE:
|
|||||||
lotus [global options] command [command options] [arguments...]
|
lotus [global options] command [command options] [arguments...]
|
||||||
|
|
||||||
VERSION:
|
VERSION:
|
||||||
1.20.1
|
1.20.2
|
||||||
|
|
||||||
COMMANDS:
|
COMMANDS:
|
||||||
daemon Start a lotus daemon process
|
daemon Start a lotus daemon process
|
||||||
|
@ -27,6 +27,7 @@ import (
|
|||||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
"github.com/filecoin-project/lotus/metrics"
|
"github.com/filecoin-project/lotus/metrics"
|
||||||
"github.com/filecoin-project/lotus/node/impl/full"
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -59,18 +60,22 @@ type TargetAPI interface {
|
|||||||
ChainPutObj(context.Context, blocks.Block) error
|
ChainPutObj(context.Context, blocks.Block) error
|
||||||
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
ChainGetGenesis(context.Context) (*types.TipSet, error)
|
||||||
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
GasEstimateMessageGas(ctx context.Context, msg *types.Message, spec *api.MessageSendSpec, tsk types.TipSetKey) (*types.Message, error)
|
||||||
|
MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error)
|
||||||
MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
MpoolPushUntrusted(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error)
|
||||||
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
MsigGetAvailableBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
MsigGetVested(ctx context.Context, addr address.Address, start types.TipSetKey, end types.TipSetKey) (types.BigInt, error)
|
||||||
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error)
|
MsigGetVestingSchedule(context.Context, address.Address, types.TipSetKey) (api.MsigVesting, error)
|
||||||
MsigGetPending(ctx context.Context, addr address.Address, ts types.TipSetKey) ([]*api.MsigTransaction, error)
|
MsigGetPending(ctx context.Context, addr address.Address, ts types.TipSetKey) ([]*api.MsigTransaction, error)
|
||||||
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateAccountKey(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
|
StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error)
|
||||||
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
|
StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error)
|
||||||
|
StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error)
|
||||||
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
StateGetActor(ctx context.Context, actor address.Address, ts types.TipSetKey) (*types.Actor, error)
|
||||||
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
StateLookupID(ctx context.Context, addr address.Address, tsk types.TipSetKey) (address.Address, error)
|
||||||
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
StateListMiners(ctx context.Context, tsk types.TipSetKey) ([]address.Address, error)
|
||||||
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
|
StateMarketBalance(ctx context.Context, addr address.Address, tsk types.TipSetKey) (api.MarketBalance, error)
|
||||||
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
|
StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, tsk types.TipSetKey) (*api.MarketDeal, error)
|
||||||
|
StateNetworkName(context.Context) (dtypes.NetworkName, error)
|
||||||
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
StateNetworkVersion(context.Context, types.TipSetKey) (network.Version, error)
|
||||||
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
StateSearchMsg(ctx context.Context, from types.TipSetKey, msg cid.Cid, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
||||||
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
StateWaitMsg(ctx context.Context, cid cid.Cid, confidence uint64, limit abi.ChainEpoch, allowReplaced bool) (*api.MsgLookup, error)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/lib/sigs"
|
||||||
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (gw *Node) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) {
|
func (gw *Node) Discover(ctx context.Context) (apitypes.OpenRPCDocument, error) {
|
||||||
@ -187,6 +188,13 @@ func (gw *Node) GasEstimateMessageGas(ctx context.Context, msg *types.Message, s
|
|||||||
return gw.target.GasEstimateMessageGas(ctx, msg, spec, tsk)
|
return gw.target.GasEstimateMessageGas(ctx, msg, spec, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gw *Node) MpoolGetNonce(ctx context.Context, addr address.Address) (uint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
return gw.target.MpoolGetNonce(ctx, addr)
|
||||||
|
}
|
||||||
|
|
||||||
func (gw *Node) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) {
|
func (gw *Node) MpoolPush(ctx context.Context, sm *types.SignedMessage) (cid.Cid, error) {
|
||||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
return cid.Cid{}, err
|
return cid.Cid{}, err
|
||||||
@ -248,6 +256,16 @@ func (gw *Node) StateAccountKey(ctx context.Context, addr address.Address, tsk t
|
|||||||
return gw.target.StateAccountKey(ctx, addr, tsk)
|
return gw.target.StateAccountKey(ctx, addr, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gw *Node) StateCall(ctx context.Context, msg *types.Message, tsk types.TipSetKey) (*api.InvocResult, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := gw.checkTipsetKey(ctx, tsk); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return gw.target.StateCall(ctx, msg, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
|
func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.PaddedPieceSize, verified bool, tsk types.TipSetKey) (api.DealCollateralBounds, error) {
|
||||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
return api.DealCollateralBounds{}, err
|
return api.DealCollateralBounds{}, err
|
||||||
@ -258,6 +276,16 @@ func (gw *Node) StateDealProviderCollateralBounds(ctx context.Context, size abi.
|
|||||||
return gw.target.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
return gw.target.StateDealProviderCollateralBounds(ctx, size, verified, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gw *Node) StateDecodeParams(ctx context.Context, toAddr address.Address, method abi.MethodNum, params []byte, tsk types.TipSetKey) (interface{}, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if err := gw.checkTipsetKey(ctx, tsk); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return gw.target.StateDecodeParams(ctx, toAddr, method, params, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
func (gw *Node) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
func (gw *Node) StateGetActor(ctx context.Context, actor address.Address, tsk types.TipSetKey) (*types.Actor, error) {
|
||||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -308,6 +336,13 @@ func (gw *Node) StateMarketStorageDeal(ctx context.Context, dealId abi.DealID, t
|
|||||||
return gw.target.StateMarketStorageDeal(ctx, dealId, tsk)
|
return gw.target.StateMarketStorageDeal(ctx, dealId, tsk)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gw *Node) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return *new(dtypes.NetworkName), err
|
||||||
|
}
|
||||||
|
return gw.target.StateNetworkName(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
func (gw *Node) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
|
func (gw *Node) StateNetworkVersion(ctx context.Context, tsk types.TipSetKey) (network.Version, error) {
|
||||||
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
return network.VersionMax, err
|
return network.VersionMax, err
|
||||||
|
@ -3,6 +3,7 @@ package itests
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -55,6 +56,10 @@ func TestEthBlockHashesCorrect_MultiBlockTipset(t *testing.T) {
|
|||||||
hex := fmt.Sprintf("0x%x", i)
|
hex := fmt.Sprintf("0x%x", i)
|
||||||
|
|
||||||
ethBlockA, err := n2.EthGetBlockByNumber(ctx, hex, true)
|
ethBlockA, err := n2.EthGetBlockByNumber(ctx, hex, true)
|
||||||
|
// Cannot use static ErrFullRound error for comparison since it gets reserialized as a JSON RPC error.
|
||||||
|
if err != nil && strings.Contains(err.Error(), "null round") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ethBlockB, err := n2.EthGetBlockByHash(ctx, ethBlockA.Hash, true)
|
ethBlockB, err := n2.EthGetBlockByHash(ctx, ethBlockA.Hash, true)
|
||||||
|
@ -3,18 +3,42 @@ package itests
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"sort"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-jsonrpc"
|
"github.com/filecoin-project/go-jsonrpc"
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
"github.com/filecoin-project/lotus/itests/kit"
|
"github.com/filecoin-project/lotus/itests/kit"
|
||||||
"github.com/filecoin-project/lotus/lib/result"
|
"github.com/filecoin-project/lotus/lib/result"
|
||||||
|
"github.com/filecoin-project/lotus/node/impl/full"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// calculateExpectations calculates the expected number of items to be included in the response
|
||||||
|
// of eth_feeHistory. It takes care of null rounds by finding the closet tipset with height
|
||||||
|
// smaller than startHeight, and then looks back at requestAmount of items. It also considers
|
||||||
|
// scenarios where there are not enough items to look back.
|
||||||
|
func calculateExpectations(tsHeights []int, requestAmount, startHeight int) (count, oldestHeight int) {
|
||||||
|
latestIdx := sort.SearchInts(tsHeights, startHeight)
|
||||||
|
// SearchInts returns the index of the number that's larger than the target if the target
|
||||||
|
// doesn't exist. However, we're looking for the closet number that's smaller that the target
|
||||||
|
for tsHeights[latestIdx] > startHeight {
|
||||||
|
latestIdx--
|
||||||
|
}
|
||||||
|
cnt := requestAmount
|
||||||
|
oldestIdx := latestIdx - requestAmount + 1
|
||||||
|
if oldestIdx < 0 {
|
||||||
|
cnt = latestIdx + 1
|
||||||
|
oldestIdx = 0
|
||||||
|
}
|
||||||
|
return cnt, tsHeights[oldestIdx]
|
||||||
|
}
|
||||||
|
|
||||||
func TestEthFeeHistory(t *testing.T) {
|
func TestEthFeeHistory(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
||||||
@ -22,70 +46,136 @@ func TestEthFeeHistory(t *testing.T) {
|
|||||||
|
|
||||||
blockTime := 100 * time.Millisecond
|
blockTime := 100 * time.Millisecond
|
||||||
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
||||||
ens.InterconnectAll().BeginMining(blockTime)
|
|
||||||
|
|
||||||
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// Wait for the network to create 20 blocks
|
heads, err := client.ChainNotify(ctx)
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
// Save the full view of the tipsets to calculate the answer when there are null rounds
|
||||||
|
tsHeights := []int{1}
|
||||||
|
go func() {
|
||||||
|
for chg := range heads {
|
||||||
|
for _, c := range chg {
|
||||||
|
tsHeights = append(tsHeights, int(c.Val.Height()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
miner := ens.InterconnectAll().BeginMining(blockTime)
|
||||||
|
|
||||||
|
client.WaitTillChain(ctx, kit.HeightAtLeast(7))
|
||||||
|
miner[0].InjectNulls(abi.ChainEpoch(5))
|
||||||
|
|
||||||
|
// Wait for the network to create at least 20 tipsets
|
||||||
client.WaitTillChain(ctx, kit.HeightAtLeast(20))
|
client.WaitTillChain(ctx, kit.HeightAtLeast(20))
|
||||||
|
for _, m := range miner {
|
||||||
|
m.Pause()
|
||||||
|
}
|
||||||
|
|
||||||
|
ch, err := client.ChainNotify(ctx)
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
// Wait for 5 seconds of inactivity
|
||||||
|
func() {
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ch:
|
||||||
|
continue
|
||||||
|
case <-time.After(5 * time.Second):
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
sort.Ints(tsHeights)
|
||||||
|
|
||||||
|
// because of the deferred execution, the last tipset is not executed yet,
|
||||||
|
// and the one before the last one is the last executed tipset,
|
||||||
|
// which corresponds to the "latest" tag in EthGetBlockByNumber
|
||||||
|
latestBlk := ethtypes.EthUint64(tsHeights[len(tsHeights)-2])
|
||||||
|
blk, err := client.EthGetBlockByNumber(ctx, "latest", false)
|
||||||
|
require.NoError(err)
|
||||||
|
require.Equal(blk.Number, latestBlk)
|
||||||
|
|
||||||
|
assertHistory := func(history *ethtypes.EthFeeHistory, requestAmount, startHeight int) {
|
||||||
|
amount, oldest := calculateExpectations(tsHeights, requestAmount, startHeight)
|
||||||
|
require.Equal(amount+1, len(history.BaseFeePerGas))
|
||||||
|
require.Equal(amount, len(history.GasUsedRatio))
|
||||||
|
require.Equal(ethtypes.EthUint64(oldest), history.OldestBlock)
|
||||||
|
}
|
||||||
|
|
||||||
history, err := client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err := client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{5, "0x10"}),
|
json.Marshal([]interface{}{5, "0x10"}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(6, len(history.BaseFeePerGas))
|
assertHistory(&history, 5, 16)
|
||||||
require.Equal(5, len(history.GasUsedRatio))
|
|
||||||
require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock)
|
|
||||||
require.Nil(history.Reward)
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{"5", "0x10"}),
|
json.Marshal([]interface{}{"5", "0x10"}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(6, len(history.BaseFeePerGas))
|
assertHistory(&history, 5, 16)
|
||||||
require.Equal(5, len(history.GasUsedRatio))
|
require.Nil(history.Reward)
|
||||||
require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock)
|
|
||||||
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
|
json.Marshal([]interface{}{5, "latest"}),
|
||||||
|
).Assert(require.NoError))
|
||||||
|
require.NoError(err)
|
||||||
|
assertHistory(&history, 5, int(latestBlk))
|
||||||
require.Nil(history.Reward)
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{"0x10", "0x12"}),
|
json.Marshal([]interface{}{"0x10", "0x12"}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(17, len(history.BaseFeePerGas))
|
assertHistory(&history, 16, 18)
|
||||||
require.Equal(16, len(history.GasUsedRatio))
|
|
||||||
require.Equal(ethtypes.EthUint64(18-16+1), history.OldestBlock)
|
|
||||||
require.Nil(history.Reward)
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{5, "0x10"}),
|
json.Marshal([]interface{}{5, "0x10"}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(6, len(history.BaseFeePerGas))
|
assertHistory(&history, 5, 16)
|
||||||
require.Equal(5, len(history.GasUsedRatio))
|
|
||||||
require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock)
|
|
||||||
require.Nil(history.Reward)
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{5, "10"}),
|
json.Marshal([]interface{}{5, "10"}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(6, len(history.BaseFeePerGas))
|
assertHistory(&history, 5, 10)
|
||||||
require.Equal(5, len(history.GasUsedRatio))
|
require.Nil(history.Reward)
|
||||||
require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock)
|
|
||||||
|
// test when the requested number of blocks is longer than chain length
|
||||||
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
|
json.Marshal([]interface{}{"0x30", "latest"}),
|
||||||
|
).Assert(require.NoError))
|
||||||
|
require.NoError(err)
|
||||||
|
assertHistory(&history, 48, int(latestBlk))
|
||||||
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
|
// test when the requested number of blocks is longer than chain length
|
||||||
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
|
json.Marshal([]interface{}{"0x30", "10"}),
|
||||||
|
).Assert(require.NoError))
|
||||||
|
require.NoError(err)
|
||||||
|
assertHistory(&history, 48, 10)
|
||||||
require.Nil(history.Reward)
|
require.Nil(history.Reward)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{5, "10", &[]float64{25, 50, 75}}),
|
json.Marshal([]interface{}{5, "10", &[]float64{25, 50, 75}}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
require.Equal(6, len(history.BaseFeePerGas))
|
assertHistory(&history, 5, 10)
|
||||||
require.Equal(5, len(history.GasUsedRatio))
|
|
||||||
require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock)
|
|
||||||
require.NotNil(history.Reward)
|
require.NotNil(history.Reward)
|
||||||
require.Equal(5, len(*history.Reward))
|
require.Equal(5, len(*history.Reward))
|
||||||
for _, arr := range *history.Reward {
|
for _, arr := range *history.Reward {
|
||||||
require.Equal(3, len(arr))
|
require.Equal(3, len(arr))
|
||||||
|
for _, item := range arr {
|
||||||
|
require.Equal(ethtypes.EthBigInt(types.NewInt(full.MinGasPremium)), item)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
@ -93,6 +183,11 @@ func TestEthFeeHistory(t *testing.T) {
|
|||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
require.Error(err)
|
require.Error(err)
|
||||||
|
|
||||||
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
|
json.Marshal([]interface{}{5, "10", &[]float64{75, 50}}),
|
||||||
|
).Assert(require.NoError))
|
||||||
|
require.Error(err)
|
||||||
|
|
||||||
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams](
|
||||||
json.Marshal([]interface{}{5, "10", &[]float64{}}),
|
json.Marshal([]interface{}{5, "10", &[]float64{}}),
|
||||||
).Assert(require.NoError))
|
).Assert(require.NoError))
|
||||||
|
@ -14,6 +14,7 @@ import (
|
|||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/build"
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
"github.com/filecoin-project/lotus/itests/kit"
|
"github.com/filecoin-project/lotus/itests/kit"
|
||||||
@ -270,6 +271,57 @@ func TestContractInvocation(t *testing.T) {
|
|||||||
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetBlockByNumber(t *testing.T) {
|
||||||
|
blockTime := 100 * time.Millisecond
|
||||||
|
client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC())
|
||||||
|
|
||||||
|
bms := ens.InterconnectAll().BeginMining(blockTime)
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
// create a new Ethereum account
|
||||||
|
_, ethAddr, filAddr := client.EVM().NewAccount()
|
||||||
|
// send some funds to the f410 address
|
||||||
|
kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10))
|
||||||
|
|
||||||
|
latest, err := client.EthBlockNumber(ctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// can get the latest block
|
||||||
|
_, err = client.EthGetBlockByNumber(ctx, latest.Hex(), true)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
// fail to get a future block
|
||||||
|
_, err = client.EthGetBlockByNumber(ctx, (latest + 10000).Hex(), true)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
// inject 10 null rounds
|
||||||
|
bms[0].InjectNulls(10)
|
||||||
|
|
||||||
|
// wait until we produce blocks again
|
||||||
|
tctx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
ch, err := client.ChainNotify(tctx)
|
||||||
|
require.NoError(t, err)
|
||||||
|
<-ch // current
|
||||||
|
hc := <-ch // wait for next block
|
||||||
|
require.Equal(t, store.HCApply, hc[0].Type)
|
||||||
|
|
||||||
|
afterNullHeight := hc[0].Val.Height()
|
||||||
|
|
||||||
|
// Fail when trying to fetch a null round.
|
||||||
|
_, err = client.EthGetBlockByNumber(ctx, (ethtypes.EthUint64(afterNullHeight - 1)).Hex(), true)
|
||||||
|
require.Error(t, err)
|
||||||
|
|
||||||
|
// Fetch balance on a null round; should not fail and should return previous balance.
|
||||||
|
// Should be lower than original balance.
|
||||||
|
bal, err := client.EthGetBalance(ctx, ethAddr, (ethtypes.EthUint64(afterNullHeight - 1)).Hex())
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEqual(t, big.Zero(), bal)
|
||||||
|
require.Equal(t, types.FromFil(10).Int, bal.Int)
|
||||||
|
}
|
||||||
|
|
||||||
func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) {
|
func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) {
|
||||||
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{
|
gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{
|
||||||
From: ðAddr,
|
From: ðAddr,
|
||||||
|
@ -153,6 +153,8 @@ type EthAPI struct {
|
|||||||
EthEventAPI
|
EthEventAPI
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var ErrNullRound = errors.New("requested epoch was a null round")
|
||||||
|
|
||||||
func (a *EthModule) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
func (a *EthModule) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
|
||||||
return stmgr.GetNetworkName(ctx, a.StateManager, a.Chain.GetHeaviestTipSet().ParentState())
|
return stmgr.GetNetworkName(ctx, a.StateManager, a.Chain.GetHeaviestTipSet().ParentState())
|
||||||
}
|
}
|
||||||
@ -231,7 +233,7 @@ func (a *EthModule) EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthH
|
|||||||
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI)
|
return newEthBlockFromFilecoinTipSet(ctx, ts, fullTxInfo, a.Chain, a.StateAPI)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string) (tipset *types.TipSet, err error) {
|
func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string, strict bool) (tipset *types.TipSet, err error) {
|
||||||
if blkParam == "earliest" {
|
if blkParam == "earliest" {
|
||||||
return nil, fmt.Errorf("block param \"earliest\" is not supported")
|
return nil, fmt.Errorf("block param \"earliest\" is not supported")
|
||||||
}
|
}
|
||||||
@ -252,16 +254,19 @@ func (a *EthModule) parseBlkParam(ctx context.Context, blkParam string) (tipset
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot parse block number: %v", err)
|
return nil, fmt.Errorf("cannot parse block number: %v", err)
|
||||||
}
|
}
|
||||||
ts, err := a.Chain.GetTipsetByHeight(ctx, abi.ChainEpoch(num), nil, false)
|
ts, err := a.Chain.GetTipsetByHeight(ctx, abi.ChainEpoch(num), nil, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot get tipset at height: %v", num)
|
return nil, fmt.Errorf("cannot get tipset at height: %v", num)
|
||||||
}
|
}
|
||||||
|
if strict && ts.Height() != abi.ChainEpoch(num) {
|
||||||
|
return nil, ErrNullRound
|
||||||
|
}
|
||||||
return ts, nil
|
return ts, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkParam string, fullTxInfo bool) (ethtypes.EthBlock, error) {
|
func (a *EthModule) EthGetBlockByNumber(ctx context.Context, blkParam string, fullTxInfo bool) (ethtypes.EthBlock, error) {
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthBlock{}, err
|
return ethtypes.EthBlock{}, err
|
||||||
}
|
}
|
||||||
@ -367,7 +372,7 @@ func (a *EthModule) EthGetTransactionCount(ctx context.Context, sender ethtypes.
|
|||||||
return ethtypes.EthUint64(0), nil
|
return ethtypes.EthUint64(0), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthUint64(0), xerrors.Errorf("cannot parse block param: %s", blkParam)
|
return ethtypes.EthUint64(0), xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||||
}
|
}
|
||||||
@ -456,7 +461,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress,
|
|||||||
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
|
return nil, xerrors.Errorf("cannot get Filecoin address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||||
}
|
}
|
||||||
@ -535,7 +540,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress,
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) {
|
func (a *EthModule) EthGetStorageAt(ctx context.Context, ethAddr ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) {
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||||
}
|
}
|
||||||
@ -631,7 +636,7 @@ func (a *EthModule) EthGetBalance(ctx context.Context, address ethtypes.EthAddre
|
|||||||
return ethtypes.EthBigInt{}, err
|
return ethtypes.EthBigInt{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthBigInt{}, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
return ethtypes.EthBigInt{}, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||||
}
|
}
|
||||||
@ -676,16 +681,12 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := a.parseBlkParam(ctx, params.NewestBlkNum)
|
ts, err := a.parseBlkParam(ctx, params.NewestBlkNum, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthFeeHistory{}, fmt.Errorf("bad block parameter %s: %s", params.NewestBlkNum, err)
|
return ethtypes.EthFeeHistory{}, fmt.Errorf("bad block parameter %s: %s", params.NewestBlkNum, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deal with the case that the chain is shorter than the number of requested blocks.
|
|
||||||
oldestBlkHeight := uint64(1)
|
oldestBlkHeight := uint64(1)
|
||||||
if abi.ChainEpoch(params.BlkCount) <= ts.Height() {
|
|
||||||
oldestBlkHeight = uint64(ts.Height()) - uint64(params.BlkCount) + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: baseFeePerGas should include the next block after the newest of the returned range,
|
// NOTE: baseFeePerGas should include the next block after the newest of the returned range,
|
||||||
// because the next base fee can be inferred from the messages in the newest block.
|
// because the next base fee can be inferred from the messages in the newest block.
|
||||||
@ -695,29 +696,32 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
|
|||||||
gasUsedRatioArray := []float64{}
|
gasUsedRatioArray := []float64{}
|
||||||
rewardsArray := make([][]ethtypes.EthBigInt, 0)
|
rewardsArray := make([][]ethtypes.EthBigInt, 0)
|
||||||
|
|
||||||
for ts.Height() >= abi.ChainEpoch(oldestBlkHeight) {
|
blocksIncluded := 0
|
||||||
// Unfortunately we need to rebuild the full message view so we can
|
for blocksIncluded < int(params.BlkCount) && ts.Height() > 0 {
|
||||||
// totalize gas used in the tipset.
|
compOutput, err := a.StateCompute(ctx, ts.Height(), nil, ts.Key())
|
||||||
msgs, err := a.Chain.MessagesForTipset(ctx, ts)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthFeeHistory{}, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err)
|
return ethtypes.EthFeeHistory{}, xerrors.Errorf("cannot lookup the status of tipset: %v: %w", ts, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
txGasRewards := gasRewardSorter{}
|
txGasRewards := gasRewardSorter{}
|
||||||
for txIdx, msg := range msgs {
|
for _, msg := range compOutput.Trace {
|
||||||
msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), api.LookbackNoLimit, false)
|
if msg.Msg.From == builtintypes.SystemActorAddr {
|
||||||
if err != nil || msgLookup == nil {
|
continue
|
||||||
return ethtypes.EthFeeHistory{}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, a.Chain, a.StateAPI)
|
smsgCid, err := getSignedMessage(ctx, a.Chain, msg.MsgCid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ethtypes.EthFeeHistory{}, nil
|
return ethtypes.EthFeeHistory{}, xerrors.Errorf("failed to get signed msg %s: %w", msg.MsgCid, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
tx, err := newEthTxFromSignedMessage(ctx, smsgCid, a.StateAPI)
|
||||||
|
if err != nil {
|
||||||
|
return ethtypes.EthFeeHistory{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
txGasRewards = append(txGasRewards, gasRewardTuple{
|
txGasRewards = append(txGasRewards, gasRewardTuple{
|
||||||
reward: tx.Reward(ts.Blocks()[0].ParentBaseFee),
|
reward: tx.Reward(ts.Blocks()[0].ParentBaseFee),
|
||||||
gas: uint64(msgLookup.Receipt.GasUsed),
|
gas: uint64(msg.MsgRct.GasUsed),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,6 +731,8 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth
|
|||||||
baseFeeArray = append(baseFeeArray, ethtypes.EthBigInt(ts.Blocks()[0].ParentBaseFee))
|
baseFeeArray = append(baseFeeArray, ethtypes.EthBigInt(ts.Blocks()[0].ParentBaseFee))
|
||||||
gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(build.BlockGasLimit))
|
gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(build.BlockGasLimit))
|
||||||
rewardsArray = append(rewardsArray, rewards)
|
rewardsArray = append(rewardsArray, rewards)
|
||||||
|
oldestBlkHeight = uint64(ts.Height())
|
||||||
|
blocksIncluded++
|
||||||
|
|
||||||
parentTsKey := ts.Parents()
|
parentTsKey := ts.Parents()
|
||||||
ts, err = a.Chain.LoadTipSet(ctx, parentTsKey)
|
ts, err = a.Chain.LoadTipSet(ctx, parentTsKey)
|
||||||
@ -1066,7 +1072,7 @@ func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam s
|
|||||||
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
|
return nil, xerrors.Errorf("failed to convert ethcall to filecoin message: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ts, err := a.parseBlkParam(ctx, blkParam)
|
ts, err := a.parseBlkParam(ctx, blkParam, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
return nil, xerrors.Errorf("cannot parse block param: %s", blkParam)
|
||||||
}
|
}
|
||||||
@ -1796,12 +1802,16 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
|||||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to compute state: %w", err)
|
return ethtypes.EthBlock{}, xerrors.Errorf("failed to compute state: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for txIdx, msg := range compOutput.Trace {
|
txIdx := 0
|
||||||
|
for _, msg := range compOutput.Trace {
|
||||||
// skip system messages like reward application and cron
|
// skip system messages like reward application and cron
|
||||||
if msg.Msg.From == builtintypes.SystemActorAddr {
|
if msg.Msg.From == builtintypes.SystemActorAddr {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ti := ethtypes.EthUint64(txIdx)
|
||||||
|
txIdx++
|
||||||
|
|
||||||
gasUsed += msg.MsgRct.GasUsed
|
gasUsed += msg.MsgRct.GasUsed
|
||||||
smsgCid, err := getSignedMessage(ctx, cs, msg.MsgCid)
|
smsgCid, err := getSignedMessage(ctx, cs, msg.MsgCid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1812,8 +1822,6 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx
|
|||||||
return ethtypes.EthBlock{}, xerrors.Errorf("failed to convert msg to ethTx: %w", err)
|
return ethtypes.EthBlock{}, xerrors.Errorf("failed to convert msg to ethTx: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ti := ethtypes.EthUint64(txIdx)
|
|
||||||
|
|
||||||
tx.ChainID = ethtypes.EthUint64(build.Eip155ChainId)
|
tx.ChainID = ethtypes.EthUint64(build.Eip155ChainId)
|
||||||
tx.BlockHash = &blkHash
|
tx.BlockHash = &blkHash
|
||||||
tx.BlockNumber = &bn
|
tx.BlockNumber = &bn
|
||||||
@ -2343,7 +2351,7 @@ func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRew
|
|||||||
|
|
||||||
rewards := make([]ethtypes.EthBigInt, len(rewardPercentiles))
|
rewards := make([]ethtypes.EthBigInt, len(rewardPercentiles))
|
||||||
for i := range rewards {
|
for i := range rewards {
|
||||||
rewards[i] = ethtypes.EthBigIntZero
|
rewards[i] = ethtypes.EthBigInt(types.NewInt(MinGasPremium))
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(txGasRewards) == 0 {
|
if len(txGasRewards) == 0 {
|
||||||
|
@ -135,7 +135,7 @@ func TestRewardPercentiles(t *testing.T) {
|
|||||||
{
|
{
|
||||||
percentiles: []float64{25, 50, 75},
|
percentiles: []float64{25, 50, 75},
|
||||||
txGasRewards: []gasRewardTuple{},
|
txGasRewards: []gasRewardTuple{},
|
||||||
answer: []int64{0, 0, 0},
|
answer: []int64{MinGasPremium, MinGasPremium, MinGasPremium},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
percentiles: []float64{25, 50, 75, 100},
|
percentiles: []float64{25, 50, 75, 100},
|
||||||
|
Loading…
Reference in New Issue
Block a user