Merge branch 'release/v1.20.0' into asr/merge-release-into-master

This commit is contained in:
Aayush 2023-01-16 10:42:49 -05:00
commit e715384173
147 changed files with 15836 additions and 1165 deletions

View File

@ -773,6 +773,54 @@ workflows:
- build
suite: itest-dup_mpool_messages
target: "./itests/dup_mpool_messages_test.go"
- test:
name: test-itest-eth_account_abstraction
requires:
- build
suite: itest-eth_account_abstraction
target: "./itests/eth_account_abstraction_test.go"
- test:
name: test-itest-eth_balance
requires:
- build
suite: itest-eth_balance
target: "./itests/eth_balance_test.go"
- test:
name: test-itest-eth_deploy
requires:
- build
suite: itest-eth_deploy
target: "./itests/eth_deploy_test.go"
- test:
name: test-itest-eth_filter
requires:
- build
suite: itest-eth_filter
target: "./itests/eth_filter_test.go"
- test:
name: test-itest-eth_transactions
requires:
- build
suite: itest-eth_transactions
target: "./itests/eth_transactions_test.go"
- test:
name: test-itest-fevm_address
requires:
- build
suite: itest-fevm_address
target: "./itests/fevm_address_test.go"
- test:
name: test-itest-fevm_events
requires:
- build
suite: itest-fevm_events
target: "./itests/fevm_events_test.go"
- test:
name: test-itest-fevm
requires:
- build
suite: itest-fevm
target: "./itests/fevm_test.go"
- test:
name: test-itest-gas_estimation
requires:
@ -815,6 +863,12 @@ workflows:
- build
suite: itest-migration_nv17
target: "./itests/migration_nv17_test.go"
- test:
name: test-itest-migration_nv18
requires:
- build
suite: itest-migration_nv18
target: "./itests/migration_nv18_test.go"
- test:
name: test-itest-mpool_msg_uuid
requires:

View File

@ -84,6 +84,12 @@ butterflynet: build-devnets
interopnet: GOFLAGS+=-tags=interopnet
interopnet: build-devnets
wallabynet: GOFLAGS+=-tags=wallabynet
wallabynet: build-devnets
hyperspacenet: GOFLAGS+=-tags=hyperspacenet
hyperspacenet: build-devnets
lotus: $(BUILD_DEPS)
rm -f lotus
$(GOCC) build $(GOFLAGS) -o lotus ./cmd/lotus

View File

@ -31,6 +31,7 @@ import (
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/actors/builtin/power"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo/imports"
)
@ -182,6 +183,9 @@ type FullNode interface {
// ChainBlockstoreInfo returns some basic information about the blockstore
ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read
// ChainGetEvents returns the events under an event AMT root CID.
ChainGetEvents(context.Context, cid.Cid) ([]types.Event, error) //perm:read
// GasEstimateFeeCap estimates gas fee cap
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read
@ -759,6 +763,77 @@ type FullNode interface {
NodeStatus(ctx context.Context, inclChainStatus bool) (NodeStatus, error) //perm:read
// MethodGroup: Eth
// These methods are used for Ethereum-compatible JSON-RPC calls
//
// EthAccounts will always return [] since we don't expect Lotus to manage private keys
EthAccounts(ctx context.Context) ([]ethtypes.EthAddress, error) //perm:read
// EthBlockNumber returns the height of the latest (heaviest) TipSet
EthBlockNumber(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
// EthGetBlockTransactionCountByNumber returns the number of messages in the TipSet
EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum ethtypes.EthUint64) (ethtypes.EthUint64, error) //perm:read
// EthGetBlockTransactionCountByHash returns the number of messages in the TipSet
EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error) //perm:read
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) //perm:read
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) //perm:read
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) //perm:read
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error) //perm:read
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) //perm:read
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) //perm:read
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) //perm:read
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) //perm:read
EthChainId(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
NetVersion(ctx context.Context) (string, error) //perm:read
NetListening(ctx context.Context) (bool, error) //perm:read
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) //perm:read
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read
EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) //perm:read
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) //perm:read
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) //perm:read
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) //perm:read
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) //perm:read
// Returns event logs matching given filter spec.
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) //perm:read
// Polling method for a filter, returns event logs which occurred since last poll.
// (requires write perm since timestamp of last filter execution will be written)
EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:write
// Returns event logs matching filter with given id.
// (requires write perm since timestamp of last filter execution will be written)
EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) //perm:write
// Installs a persistent filter based on given filter spec.
EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) //perm:write
// Installs a persistent filter to notify when a new block arrives.
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:write
// Installs a persistent filter to notify when new messages arrive in the message pool.
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) //perm:write
// Uninstalls a filter with given id.
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) //perm:write
// Subscribe to different event types using websockets
// eventTypes is one or more of:
// - newHeads: notify when new blocks arrive.
// - pendingTransactions: notify when new messages arrive in the message pool.
// - logs: notify new event logs that match a criteria
// params contains additional parameters used with the log event type
// The client will receive a stream of EthSubscriptionResponse values until EthUnsubscribe is called.
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) //perm:write
// Unsubscribe from a websocket subscription
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) //perm:write
// CreateBackup creates node backup onder the specified file name. The
// method requires that the lotus daemon is running with the
// LOTUS_BACKUP_BASE_PATH environment variable set to some path, and that
@ -1252,3 +1327,21 @@ type PruneOpts struct {
MovingGC bool
RetainState int64
}
type EthTxReceipt struct {
TransactionHash ethtypes.EthHash `json:"transactionHash"`
TransactionIndex ethtypes.EthUint64 `json:"transactionIndex"`
BlockHash ethtypes.EthHash `json:"blockHash"`
BlockNumber ethtypes.EthUint64 `json:"blockNumber"`
From ethtypes.EthAddress `json:"from"`
To *ethtypes.EthAddress `json:"to"`
StateRoot ethtypes.EthHash `json:"root"`
Status ethtypes.EthUint64 `json:"status"`
ContractAddress *ethtypes.EthAddress `json:"contractAddress"`
CumulativeGasUsed ethtypes.EthUint64 `json:"cumulativeGasUsed"`
GasUsed ethtypes.EthUint64 `json:"gasUsed"`
EffectiveGasPrice ethtypes.EthBigInt `json:"effectiveGasPrice"`
LogsBloom ethtypes.EthBytes `json:"logsBloom"`
Logs []ethtypes.EthLog `json:"logs"`
Type ethtypes.EthUint64 `json:"type"`
}

View File

@ -13,6 +13,7 @@ import (
apitypes "github.com/filecoin-project/lotus/api/types"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
)
// MODIFYING THE API INTERFACE
@ -69,4 +70,38 @@ type Gateway interface {
WalletBalance(context.Context, address.Address) (types.BigInt, error)
Version(context.Context) (APIVersion, error)
Discover(context.Context) (apitypes.OpenRPCDocument, error)
EthAccounts(ctx context.Context) ([]ethtypes.EthAddress, error)
EthBlockNumber(ctx context.Context) (ethtypes.EthUint64, error)
EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum ethtypes.EthUint64) (ethtypes.EthUint64, error)
EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error)
EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error)
EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error)
EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error)
EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error)
EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*EthTxReceipt, error)
EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error)
EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error)
EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error)
EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error)
EthChainId(ctx context.Context) (ethtypes.EthUint64, error)
NetVersion(ctx context.Context) (string, error)
NetListening(ctx context.Context) (bool, error)
EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error)
EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error)
EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error)
EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error)
EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error)
EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error)
EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error)
EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error)
EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error)
EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error)
EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error)
EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error)
EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error)
EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error)
EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error)
EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error)
}

View File

@ -22,7 +22,7 @@ import (
"github.com/filecoin-project/go-state-types/builtin/v9/miner"
abinetwork "github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors/builtin"
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/storage/pipeline/sealiface"
"github.com/filecoin-project/lotus/storage/sealer/fsutil"
@ -152,7 +152,7 @@ type StorageMiner interface {
WorkerStats(context.Context) (map[uuid.UUID]storiface.WorkerStats, error) //perm:admin
WorkerJobs(context.Context) (map[uuid.UUID][]storiface.WorkerJob, error) //perm:admin
//storiface.WorkerReturn
// storiface.WorkerReturn
ReturnDataCid(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error //perm:admin retry:true
ReturnAddPiece(ctx context.Context, callID storiface.CallID, pi abi.PieceInfo, err *storiface.CallError) error //perm:admin retry:true
ReturnSealPreCommit1(ctx context.Context, callID storiface.CallID, p1o storiface.PreCommit1Out, err *storiface.CallError) error //perm:admin retry:true
@ -175,7 +175,7 @@ type StorageMiner interface {
// SealingSchedDiag dumps internal sealing scheduler state
SealingSchedDiag(ctx context.Context, doSched bool) (interface{}, error) //perm:admin
SealingAbort(ctx context.Context, call storiface.CallID) error //perm:admin
//SealingSchedRemove removes a request from sealing pipeline
// SealingSchedRemove removes a request from sealing pipeline
SealingRemoveRequest(ctx context.Context, schedId uuid.UUID) error //perm:admin
// paths.SectorIndex
@ -322,7 +322,7 @@ type StorageMiner interface {
CheckProvable(ctx context.Context, pp abi.RegisteredPoStProof, sectors []storiface.SectorRef) (map[abi.SectorNumber]string, error) //perm:admin
ComputeProof(ctx context.Context, ssi []builtin.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtin.PoStProof, error) //perm:read
ComputeProof(ctx context.Context, ssi []builtinactors.ExtendedSectorInfo, rand abi.PoStRandomness, poStEpoch abi.ChainEpoch, nv abinetwork.Version) ([]builtinactors.PoStProof, error) //perm:read
// RecoverFault can be used to declare recoveries manually. It sends messages
// to the miner actor with details of recovered sectors and returns the CID of messages. It honors the

View File

@ -41,6 +41,7 @@ import (
"github.com/filecoin-project/lotus/api/v0api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo/imports"
sealing "github.com/filecoin-project/lotus/storage/pipeline"
@ -68,6 +69,7 @@ func init() {
}
ExampleValues[reflect.TypeOf(c)] = c
ExampleValues[reflect.TypeOf(&c)] = &c
c2, err := cid.Decode("bafy2bzacebp3shtrn43k7g3unredz7fxn4gj533d3o43tqn2p2ipxxhrvchve")
if err != nil {
@ -298,7 +300,8 @@ func init() {
"title": "Lotus RPC API",
"version": "1.2.1/generated=2020-11-22T08:22:42-06:00",
},
"methods": []interface{}{}},
"methods": []interface{}{},
},
)
addExample(api.CheckStatusCode(0))
@ -335,7 +338,8 @@ func init() {
NumConnsInbound: 3,
NumConnsOutbound: 4,
NumFD: 5,
}})
},
})
addExample(api.NetLimit{
Memory: 123,
StreamsInbound: 1,
@ -346,6 +350,7 @@ func init() {
Conns: 4,
FD: 5,
})
addExample(map[string]bitfield.BitField{
"": bitfield.NewFromSet([]uint64{5, 6, 7, 10}),
})
@ -365,11 +370,40 @@ func init() {
Headers: nil,
},
})
ethint := ethtypes.EthUint64(5)
addExample(ethint)
addExample(&ethint)
ethaddr, _ := ethtypes.ParseEthAddress("0x5CbEeCF99d3fDB3f25E309Cc264f240bb0664031")
addExample(ethaddr)
addExample(&ethaddr)
ethhash, _ := ethtypes.EthHashFromCid(c)
addExample(ethhash)
addExample(&ethhash)
ethFeeHistoryReward := [][]ethtypes.EthBigInt{}
addExample(&ethFeeHistoryReward)
addExample(&uuid.UUID{})
filterid := ethtypes.EthFilterID(ethhash)
addExample(filterid)
addExample(&filterid)
subid := ethtypes.EthSubscriptionID(ethhash)
addExample(subid)
addExample(&subid)
pstring := func(s string) *string { return &s }
addExample(&ethtypes.EthFilterSpec{
FromBlock: pstring("2301220"),
Address: []ethtypes.EthAddress{ethaddr},
})
}
func GetAPIType(name, pkg string) (i interface{}, t reflect.Type, permStruct []reflect.Type) {
switch pkg {
case "api": // latest
switch name {
@ -439,7 +473,7 @@ func ExampleValue(method string, t, parent reflect.Type) interface{} {
case reflect.Ptr:
if t.Elem().Kind() == reflect.Struct {
es := exampleStruct(method, t.Elem(), t)
// ExampleValues[t] = es
ExampleValues[t] = es
return es
}
case reflect.Interface:

44
api/eth_aliases.go Normal file
View File

@ -0,0 +1,44 @@
package api
import apitypes "github.com/filecoin-project/lotus/api/types"
func CreateEthRPCAliases(as apitypes.Aliaser) {
// TODO: maybe use reflect to automatically register all the eth aliases
as.AliasMethod("eth_accounts", "Filecoin.EthAccounts")
as.AliasMethod("eth_blockNumber", "Filecoin.EthBlockNumber")
as.AliasMethod("eth_getBlockTransactionCountByNumber", "Filecoin.EthGetBlockTransactionCountByNumber")
as.AliasMethod("eth_getBlockTransactionCountByHash", "Filecoin.EthGetBlockTransactionCountByHash")
as.AliasMethod("eth_getBlockByHash", "Filecoin.EthGetBlockByHash")
as.AliasMethod("eth_getBlockByNumber", "Filecoin.EthGetBlockByNumber")
as.AliasMethod("eth_getTransactionByHash", "Filecoin.EthGetTransactionByHash")
as.AliasMethod("eth_getTransactionCount", "Filecoin.EthGetTransactionCount")
as.AliasMethod("eth_getTransactionReceipt", "Filecoin.EthGetTransactionReceipt")
as.AliasMethod("eth_getTransactionByBlockHashAndIndex", "Filecoin.EthGetTransactionByBlockHashAndIndex")
as.AliasMethod("eth_getTransactionByBlockNumberAndIndex", "Filecoin.EthGetTransactionByBlockNumberAndIndex")
as.AliasMethod("eth_getCode", "Filecoin.EthGetCode")
as.AliasMethod("eth_getStorageAt", "Filecoin.EthGetStorageAt")
as.AliasMethod("eth_getBalance", "Filecoin.EthGetBalance")
as.AliasMethod("eth_chainId", "Filecoin.EthChainId")
as.AliasMethod("eth_feeHistory", "Filecoin.EthFeeHistory")
as.AliasMethod("eth_protocolVersion", "Filecoin.EthProtocolVersion")
as.AliasMethod("eth_maxPriorityFeePerGas", "Filecoin.EthMaxPriorityFeePerGas")
as.AliasMethod("eth_gasPrice", "Filecoin.EthGasPrice")
as.AliasMethod("eth_sendRawTransaction", "Filecoin.EthSendRawTransaction")
as.AliasMethod("eth_estimateGas", "Filecoin.EthEstimateGas")
as.AliasMethod("eth_call", "Filecoin.EthCall")
as.AliasMethod("eth_getLogs", "Filecoin.EthGetLogs")
as.AliasMethod("eth_getFilterChanges", "Filecoin.EthGetFilterChanges")
as.AliasMethod("eth_getFilterLogs", "Filecoin.EthGetFilterLogs")
as.AliasMethod("eth_newFilter", "Filecoin.EthNewFilter")
as.AliasMethod("eth_newBlockFilter", "Filecoin.EthNewBlockFilter")
as.AliasMethod("eth_newPendingTransactionFilter", "Filecoin.EthNewPendingTransactionFilter")
as.AliasMethod("eth_uninstallFilter", "Filecoin.EthUninstallFilter")
as.AliasMethod("eth_subscribe", "Filecoin.EthSubscribe")
as.AliasMethod("eth_unsubscribe", "Filecoin.EthUnsubscribe")
as.AliasMethod("net_version", "Filecoin.NetVersion")
as.AliasMethod("net_listening", "Filecoin.NetListening")
}

View File

@ -37,6 +37,7 @@ import (
apitypes "github.com/filecoin-project/lotus/api/types"
miner0 "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
types "github.com/filecoin-project/lotus/chain/types"
ethtypes "github.com/filecoin-project/lotus/chain/types/ethtypes"
alerting "github.com/filecoin-project/lotus/journal/alerting"
dtypes "github.com/filecoin-project/lotus/node/modules/dtypes"
imports "github.com/filecoin-project/lotus/node/repo/imports"
@ -183,6 +184,21 @@ func (mr *MockFullNodeMockRecorder) ChainGetBlockMessages(arg0, arg1 interface{}
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetBlockMessages", reflect.TypeOf((*MockFullNode)(nil).ChainGetBlockMessages), arg0, arg1)
}
// ChainGetEvents mocks base method.
func (m *MockFullNode) ChainGetEvents(arg0 context.Context, arg1 cid.Cid) ([]types.Event, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "ChainGetEvents", arg0, arg1)
ret0, _ := ret[0].([]types.Event)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// ChainGetEvents indicates an expected call of ChainGetEvents.
func (mr *MockFullNodeMockRecorder) ChainGetEvents(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChainGetEvents", reflect.TypeOf((*MockFullNode)(nil).ChainGetEvents), arg0, arg1)
}
// ChainGetGenesis mocks base method.
func (m *MockFullNode) ChainGetGenesis(arg0 context.Context) (*types.TipSet, error) {
m.ctrl.T.Helper()
@ -921,6 +937,471 @@ func (mr *MockFullNodeMockRecorder) Discover(arg0 interface{}) *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Discover", reflect.TypeOf((*MockFullNode)(nil).Discover), arg0)
}
// EthAccounts mocks base method.
func (m *MockFullNode) EthAccounts(arg0 context.Context) ([]ethtypes.EthAddress, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthAccounts", arg0)
ret0, _ := ret[0].([]ethtypes.EthAddress)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthAccounts indicates an expected call of EthAccounts.
func (mr *MockFullNodeMockRecorder) EthAccounts(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthAccounts", reflect.TypeOf((*MockFullNode)(nil).EthAccounts), arg0)
}
// EthBlockNumber mocks base method.
func (m *MockFullNode) EthBlockNumber(arg0 context.Context) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthBlockNumber", arg0)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthBlockNumber indicates an expected call of EthBlockNumber.
func (mr *MockFullNodeMockRecorder) EthBlockNumber(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthBlockNumber", reflect.TypeOf((*MockFullNode)(nil).EthBlockNumber), arg0)
}
// EthCall mocks base method.
func (m *MockFullNode) EthCall(arg0 context.Context, arg1 ethtypes.EthCall, arg2 string) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthCall", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBytes)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthCall indicates an expected call of EthCall.
func (mr *MockFullNodeMockRecorder) EthCall(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthCall", reflect.TypeOf((*MockFullNode)(nil).EthCall), arg0, arg1, arg2)
}
// EthChainId mocks base method.
func (m *MockFullNode) EthChainId(arg0 context.Context) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthChainId", arg0)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthChainId indicates an expected call of EthChainId.
func (mr *MockFullNodeMockRecorder) EthChainId(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthChainId", reflect.TypeOf((*MockFullNode)(nil).EthChainId), arg0)
}
// EthEstimateGas mocks base method.
func (m *MockFullNode) EthEstimateGas(arg0 context.Context, arg1 ethtypes.EthCall) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthEstimateGas", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthEstimateGas indicates an expected call of EthEstimateGas.
func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthEstimateGas", reflect.TypeOf((*MockFullNode)(nil).EthEstimateGas), arg0, arg1)
}
// EthFeeHistory mocks base method.
func (m *MockFullNode) EthFeeHistory(arg0 context.Context, arg1 ethtypes.EthUint64, arg2 string, arg3 []float64) (ethtypes.EthFeeHistory, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthFeeHistory", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(ethtypes.EthFeeHistory)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthFeeHistory indicates an expected call of EthFeeHistory.
func (mr *MockFullNodeMockRecorder) EthFeeHistory(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthFeeHistory", reflect.TypeOf((*MockFullNode)(nil).EthFeeHistory), arg0, arg1, arg2, arg3)
}
// EthGasPrice mocks base method.
func (m *MockFullNode) EthGasPrice(arg0 context.Context) (ethtypes.EthBigInt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGasPrice", arg0)
ret0, _ := ret[0].(ethtypes.EthBigInt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGasPrice indicates an expected call of EthGasPrice.
func (mr *MockFullNodeMockRecorder) EthGasPrice(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGasPrice", reflect.TypeOf((*MockFullNode)(nil).EthGasPrice), arg0)
}
// EthGetBalance mocks base method.
func (m *MockFullNode) EthGetBalance(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthBigInt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBalance", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBigInt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetBalance indicates an expected call of EthGetBalance.
func (mr *MockFullNodeMockRecorder) EthGetBalance(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetBalance", reflect.TypeOf((*MockFullNode)(nil).EthGetBalance), arg0, arg1, arg2)
}
// EthGetBlockByHash mocks base method.
func (m *MockFullNode) EthGetBlockByHash(arg0 context.Context, arg1 ethtypes.EthHash, arg2 bool) (ethtypes.EthBlock, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBlockByHash", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBlock)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetBlockByHash indicates an expected call of EthGetBlockByHash.
func (mr *MockFullNodeMockRecorder) EthGetBlockByHash(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetBlockByHash", reflect.TypeOf((*MockFullNode)(nil).EthGetBlockByHash), arg0, arg1, arg2)
}
// EthGetBlockByNumber mocks base method.
func (m *MockFullNode) EthGetBlockByNumber(arg0 context.Context, arg1 string, arg2 bool) (ethtypes.EthBlock, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBlockByNumber", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBlock)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetBlockByNumber indicates an expected call of EthGetBlockByNumber.
func (mr *MockFullNodeMockRecorder) EthGetBlockByNumber(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetBlockByNumber", reflect.TypeOf((*MockFullNode)(nil).EthGetBlockByNumber), arg0, arg1, arg2)
}
// EthGetBlockTransactionCountByHash mocks base method.
func (m *MockFullNode) EthGetBlockTransactionCountByHash(arg0 context.Context, arg1 ethtypes.EthHash) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBlockTransactionCountByHash", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetBlockTransactionCountByHash indicates an expected call of EthGetBlockTransactionCountByHash.
func (mr *MockFullNodeMockRecorder) EthGetBlockTransactionCountByHash(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetBlockTransactionCountByHash", reflect.TypeOf((*MockFullNode)(nil).EthGetBlockTransactionCountByHash), arg0, arg1)
}
// EthGetBlockTransactionCountByNumber mocks base method.
func (m *MockFullNode) EthGetBlockTransactionCountByNumber(arg0 context.Context, arg1 ethtypes.EthUint64) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetBlockTransactionCountByNumber", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetBlockTransactionCountByNumber indicates an expected call of EthGetBlockTransactionCountByNumber.
func (mr *MockFullNodeMockRecorder) EthGetBlockTransactionCountByNumber(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetBlockTransactionCountByNumber", reflect.TypeOf((*MockFullNode)(nil).EthGetBlockTransactionCountByNumber), arg0, arg1)
}
// EthGetCode mocks base method.
func (m *MockFullNode) EthGetCode(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetCode", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthBytes)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetCode indicates an expected call of EthGetCode.
func (mr *MockFullNodeMockRecorder) EthGetCode(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetCode", reflect.TypeOf((*MockFullNode)(nil).EthGetCode), arg0, arg1, arg2)
}
// EthGetFilterChanges mocks base method.
func (m *MockFullNode) EthGetFilterChanges(arg0 context.Context, arg1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetFilterChanges", arg0, arg1)
ret0, _ := ret[0].(*ethtypes.EthFilterResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetFilterChanges indicates an expected call of EthGetFilterChanges.
func (mr *MockFullNodeMockRecorder) EthGetFilterChanges(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetFilterChanges", reflect.TypeOf((*MockFullNode)(nil).EthGetFilterChanges), arg0, arg1)
}
// EthGetFilterLogs mocks base method.
func (m *MockFullNode) EthGetFilterLogs(arg0 context.Context, arg1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetFilterLogs", arg0, arg1)
ret0, _ := ret[0].(*ethtypes.EthFilterResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetFilterLogs indicates an expected call of EthGetFilterLogs.
func (mr *MockFullNodeMockRecorder) EthGetFilterLogs(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetFilterLogs", reflect.TypeOf((*MockFullNode)(nil).EthGetFilterLogs), arg0, arg1)
}
// EthGetLogs mocks base method.
func (m *MockFullNode) EthGetLogs(arg0 context.Context, arg1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetLogs", arg0, arg1)
ret0, _ := ret[0].(*ethtypes.EthFilterResult)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetLogs indicates an expected call of EthGetLogs.
func (mr *MockFullNodeMockRecorder) EthGetLogs(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetLogs", reflect.TypeOf((*MockFullNode)(nil).EthGetLogs), arg0, arg1)
}
// EthGetStorageAt mocks base method.
func (m *MockFullNode) EthGetStorageAt(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 ethtypes.EthBytes, arg3 string) (ethtypes.EthBytes, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetStorageAt", arg0, arg1, arg2, arg3)
ret0, _ := ret[0].(ethtypes.EthBytes)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetStorageAt indicates an expected call of EthGetStorageAt.
func (mr *MockFullNodeMockRecorder) EthGetStorageAt(arg0, arg1, arg2, arg3 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetStorageAt", reflect.TypeOf((*MockFullNode)(nil).EthGetStorageAt), arg0, arg1, arg2, arg3)
}
// EthGetTransactionByBlockHashAndIndex mocks base method.
func (m *MockFullNode) EthGetTransactionByBlockHashAndIndex(arg0 context.Context, arg1 ethtypes.EthHash, arg2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionByBlockHashAndIndex", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthTx)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionByBlockHashAndIndex indicates an expected call of EthGetTransactionByBlockHashAndIndex.
func (mr *MockFullNodeMockRecorder) EthGetTransactionByBlockHashAndIndex(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByBlockHashAndIndex", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByBlockHashAndIndex), arg0, arg1, arg2)
}
// EthGetTransactionByBlockNumberAndIndex mocks base method.
func (m *MockFullNode) EthGetTransactionByBlockNumberAndIndex(arg0 context.Context, arg1, arg2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionByBlockNumberAndIndex", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthTx)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionByBlockNumberAndIndex indicates an expected call of EthGetTransactionByBlockNumberAndIndex.
func (mr *MockFullNodeMockRecorder) EthGetTransactionByBlockNumberAndIndex(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByBlockNumberAndIndex", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByBlockNumberAndIndex), arg0, arg1, arg2)
}
// EthGetTransactionByHash mocks base method.
func (m *MockFullNode) EthGetTransactionByHash(arg0 context.Context, arg1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionByHash", arg0, arg1)
ret0, _ := ret[0].(*ethtypes.EthTx)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionByHash indicates an expected call of EthGetTransactionByHash.
func (mr *MockFullNodeMockRecorder) EthGetTransactionByHash(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionByHash", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionByHash), arg0, arg1)
}
// EthGetTransactionCount mocks base method.
func (m *MockFullNode) EthGetTransactionCount(arg0 context.Context, arg1 ethtypes.EthAddress, arg2 string) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionCount", arg0, arg1, arg2)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionCount indicates an expected call of EthGetTransactionCount.
func (mr *MockFullNodeMockRecorder) EthGetTransactionCount(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionCount", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionCount), arg0, arg1, arg2)
}
// EthGetTransactionReceipt mocks base method.
func (m *MockFullNode) EthGetTransactionReceipt(arg0 context.Context, arg1 ethtypes.EthHash) (*api.EthTxReceipt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthGetTransactionReceipt", arg0, arg1)
ret0, _ := ret[0].(*api.EthTxReceipt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthGetTransactionReceipt indicates an expected call of EthGetTransactionReceipt.
func (mr *MockFullNodeMockRecorder) EthGetTransactionReceipt(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthGetTransactionReceipt", reflect.TypeOf((*MockFullNode)(nil).EthGetTransactionReceipt), arg0, arg1)
}
// EthMaxPriorityFeePerGas mocks base method.
func (m *MockFullNode) EthMaxPriorityFeePerGas(arg0 context.Context) (ethtypes.EthBigInt, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthMaxPriorityFeePerGas", arg0)
ret0, _ := ret[0].(ethtypes.EthBigInt)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthMaxPriorityFeePerGas indicates an expected call of EthMaxPriorityFeePerGas.
func (mr *MockFullNodeMockRecorder) EthMaxPriorityFeePerGas(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthMaxPriorityFeePerGas", reflect.TypeOf((*MockFullNode)(nil).EthMaxPriorityFeePerGas), arg0)
}
// EthNewBlockFilter mocks base method.
func (m *MockFullNode) EthNewBlockFilter(arg0 context.Context) (ethtypes.EthFilterID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthNewBlockFilter", arg0)
ret0, _ := ret[0].(ethtypes.EthFilterID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthNewBlockFilter indicates an expected call of EthNewBlockFilter.
func (mr *MockFullNodeMockRecorder) EthNewBlockFilter(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthNewBlockFilter", reflect.TypeOf((*MockFullNode)(nil).EthNewBlockFilter), arg0)
}
// EthNewFilter mocks base method.
func (m *MockFullNode) EthNewFilter(arg0 context.Context, arg1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthNewFilter", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthFilterID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthNewFilter indicates an expected call of EthNewFilter.
func (mr *MockFullNodeMockRecorder) EthNewFilter(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthNewFilter", reflect.TypeOf((*MockFullNode)(nil).EthNewFilter), arg0, arg1)
}
// EthNewPendingTransactionFilter mocks base method.
func (m *MockFullNode) EthNewPendingTransactionFilter(arg0 context.Context) (ethtypes.EthFilterID, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthNewPendingTransactionFilter", arg0)
ret0, _ := ret[0].(ethtypes.EthFilterID)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthNewPendingTransactionFilter indicates an expected call of EthNewPendingTransactionFilter.
func (mr *MockFullNodeMockRecorder) EthNewPendingTransactionFilter(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthNewPendingTransactionFilter", reflect.TypeOf((*MockFullNode)(nil).EthNewPendingTransactionFilter), arg0)
}
// EthProtocolVersion mocks base method.
func (m *MockFullNode) EthProtocolVersion(arg0 context.Context) (ethtypes.EthUint64, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthProtocolVersion", arg0)
ret0, _ := ret[0].(ethtypes.EthUint64)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthProtocolVersion indicates an expected call of EthProtocolVersion.
func (mr *MockFullNodeMockRecorder) EthProtocolVersion(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthProtocolVersion", reflect.TypeOf((*MockFullNode)(nil).EthProtocolVersion), arg0)
}
// EthSendRawTransaction mocks base method.
func (m *MockFullNode) EthSendRawTransaction(arg0 context.Context, arg1 ethtypes.EthBytes) (ethtypes.EthHash, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthSendRawTransaction", arg0, arg1)
ret0, _ := ret[0].(ethtypes.EthHash)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthSendRawTransaction indicates an expected call of EthSendRawTransaction.
func (mr *MockFullNodeMockRecorder) EthSendRawTransaction(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSendRawTransaction", reflect.TypeOf((*MockFullNode)(nil).EthSendRawTransaction), arg0, arg1)
}
// EthSubscribe mocks base method.
func (m *MockFullNode) EthSubscribe(arg0 context.Context, arg1 string, arg2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthSubscribe", arg0, arg1, arg2)
ret0, _ := ret[0].(<-chan ethtypes.EthSubscriptionResponse)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthSubscribe indicates an expected call of EthSubscribe.
func (mr *MockFullNodeMockRecorder) EthSubscribe(arg0, arg1, arg2 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthSubscribe", reflect.TypeOf((*MockFullNode)(nil).EthSubscribe), arg0, arg1, arg2)
}
// EthUninstallFilter mocks base method.
func (m *MockFullNode) EthUninstallFilter(arg0 context.Context, arg1 ethtypes.EthFilterID) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthUninstallFilter", arg0, arg1)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthUninstallFilter indicates an expected call of EthUninstallFilter.
func (mr *MockFullNodeMockRecorder) EthUninstallFilter(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthUninstallFilter", reflect.TypeOf((*MockFullNode)(nil).EthUninstallFilter), arg0, arg1)
}
// EthUnsubscribe mocks base method.
func (m *MockFullNode) EthUnsubscribe(arg0 context.Context, arg1 ethtypes.EthSubscriptionID) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "EthUnsubscribe", arg0, arg1)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// EthUnsubscribe indicates an expected call of EthUnsubscribe.
func (mr *MockFullNodeMockRecorder) EthUnsubscribe(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthUnsubscribe", reflect.TypeOf((*MockFullNode)(nil).EthUnsubscribe), arg0, arg1)
}
// GasEstimateFeeCap mocks base method.
func (m *MockFullNode) GasEstimateFeeCap(arg0 context.Context, arg1 *types.Message, arg2 int64, arg3 types.TipSetKey) (big.Int, error) {
m.ctrl.T.Helper()
@ -1843,6 +2324,21 @@ func (mr *MockFullNodeMockRecorder) NetLimit(arg0, arg1 interface{}) *gomock.Cal
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetLimit", reflect.TypeOf((*MockFullNode)(nil).NetLimit), arg0, arg1)
}
// NetListening mocks base method.
func (m *MockFullNode) NetListening(arg0 context.Context) (bool, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetListening", arg0)
ret0, _ := ret[0].(bool)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetListening indicates an expected call of NetListening.
func (mr *MockFullNodeMockRecorder) NetListening(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetListening", reflect.TypeOf((*MockFullNode)(nil).NetListening), arg0)
}
// NetPeerInfo mocks base method.
func (m *MockFullNode) NetPeerInfo(arg0 context.Context, arg1 peer.ID) (*api.ExtendedPeerInfo, error) {
m.ctrl.T.Helper()
@ -1975,6 +2471,21 @@ func (mr *MockFullNodeMockRecorder) NetStat(arg0, arg1 interface{}) *gomock.Call
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetStat", reflect.TypeOf((*MockFullNode)(nil).NetStat), arg0, arg1)
}
// NetVersion mocks base method.
func (m *MockFullNode) NetVersion(arg0 context.Context) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "NetVersion", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// NetVersion indicates an expected call of NetVersion.
func (mr *MockFullNodeMockRecorder) NetVersion(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NetVersion", reflect.TypeOf((*MockFullNode)(nil).NetVersion), arg0)
}
// NodeStatus mocks base method.
func (m *MockFullNode) NodeStatus(arg0 context.Context, arg1 bool) (api.NodeStatus, error) {
m.ctrl.T.Helper()

View File

@ -33,9 +33,10 @@ import (
"github.com/filecoin-project/go-state-types/proof"
apitypes "github.com/filecoin-project/lotus/api/types"
"github.com/filecoin-project/lotus/chain/actors/builtin"
builtinactors "github.com/filecoin-project/lotus/chain/actors/builtin"
lminer "github.com/filecoin-project/lotus/chain/actors/builtin/miner"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/journal/alerting"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/repo/imports"
@ -122,6 +123,8 @@ type FullNodeStruct struct {
ChainGetBlockMessages func(p0 context.Context, p1 cid.Cid) (*BlockMessages, error) `perm:"read"`
ChainGetEvents func(p0 context.Context, p1 cid.Cid) ([]types.Event, error) `perm:"read"`
ChainGetGenesis func(p0 context.Context) (*types.TipSet, error) `perm:"read"`
ChainGetMessage func(p0 context.Context, p1 cid.Cid) (*types.Message, error) `perm:"read"`
@ -218,6 +221,68 @@ type FullNodeStruct struct {
CreateBackup func(p0 context.Context, p1 string) error `perm:"admin"`
EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) `perm:"read"`
EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) `perm:"read"`
EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) `perm:"read"`
EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) `perm:"read"`
EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"`
EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) `perm:"read"`
EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) `perm:"read"`
EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) `perm:"read"`
EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) `perm:"read"`
EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) `perm:"read"`
EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) `perm:"read"`
EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"`
EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) `perm:"write"`
EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) `perm:"read"`
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) `perm:"read"`
EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) `perm:"read"`
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) `perm:"read"`
EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) `perm:"read"`
EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"`
EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"`
EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) `perm:"write"`
EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) `perm:"write"`
EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) `perm:"read"`
EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) `perm:"read"`
EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) `perm:"write"`
EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) `perm:"write"`
EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) `perm:"write"`
GasEstimateFeeCap func(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) `perm:"read"`
GasEstimateGasLimit func(p0 context.Context, p1 *types.Message, p2 types.TipSetKey) (int64, error) `perm:"read"`
@ -306,6 +371,10 @@ type FullNodeStruct struct {
MsigSwapPropose func(p0 context.Context, p1 address.Address, p2 address.Address, p3 address.Address, p4 address.Address) (*MessagePrototype, error) `perm:"sign"`
NetListening func(p0 context.Context) (bool, error) `perm:"read"`
NetVersion func(p0 context.Context) (string, error) `perm:"read"`
NodeStatus func(p0 context.Context, p1 bool) (NodeStatus, error) `perm:"read"`
PaychAllocateLane func(p0 context.Context, p1 address.Address) (uint64, error) `perm:"sign"`
@ -550,6 +619,68 @@ type GatewayStruct struct {
Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) ``
EthAccounts func(p0 context.Context) ([]ethtypes.EthAddress, error) ``
EthBlockNumber func(p0 context.Context) (ethtypes.EthUint64, error) ``
EthCall func(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) ``
EthChainId func(p0 context.Context) (ethtypes.EthUint64, error) ``
EthEstimateGas func(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) ``
EthFeeHistory func(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) ``
EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) ``
EthGetBalance func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) ``
EthGetBlockByHash func(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) ``
EthGetBlockByNumber func(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) ``
EthGetBlockTransactionCountByHash func(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) ``
EthGetBlockTransactionCountByNumber func(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) ``
EthGetCode func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) ``
EthGetFilterChanges func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) ``
EthGetFilterLogs func(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) ``
EthGetLogs func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) ``
EthGetStorageAt func(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) ``
EthGetTransactionByBlockHashAndIndex func(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) ``
EthGetTransactionByBlockNumberAndIndex func(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) ``
EthGetTransactionByHash func(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) ``
EthGetTransactionCount func(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) ``
EthGetTransactionReceipt func(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) ``
EthMaxPriorityFeePerGas func(p0 context.Context) (ethtypes.EthBigInt, error) ``
EthNewBlockFilter func(p0 context.Context) (ethtypes.EthFilterID, error) ``
EthNewFilter func(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) ``
EthNewPendingTransactionFilter func(p0 context.Context) (ethtypes.EthFilterID, error) ``
EthProtocolVersion func(p0 context.Context) (ethtypes.EthUint64, error) ``
EthSendRawTransaction func(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) ``
EthSubscribe func(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) ``
EthUninstallFilter func(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) ``
EthUnsubscribe func(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) ``
GasEstimateMessageGas func(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) ``
MpoolPush func(p0 context.Context, p1 *types.SignedMessage) (cid.Cid, error) ``
@ -562,6 +693,10 @@ type GatewayStruct struct {
MsigGetVestingSchedule func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (MsigVesting, error) ``
NetListening func(p0 context.Context) (bool, error) ``
NetVersion func(p0 context.Context) (string, error) ``
StateAccountKey func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) ``
StateDealProviderCollateralBounds func(p0 context.Context, p1 abi.PaddedPieceSize, p2 bool, p3 types.TipSetKey) (DealCollateralBounds, error) ``
@ -687,7 +822,7 @@ type StorageMinerStruct struct {
ComputeDataCid func(p0 context.Context, p1 abi.UnpaddedPieceSize, p2 storiface.Data) (abi.PieceInfo, error) `perm:"admin"`
ComputeProof func(p0 context.Context, p1 []builtin.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtin.PoStProof, error) `perm:"read"`
ComputeProof func(p0 context.Context, p1 []builtinactors.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtinactors.PoStProof, error) `perm:"read"`
ComputeWindowPoSt func(p0 context.Context, p1 uint64, p2 types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) `perm:"admin"`
@ -1267,6 +1402,17 @@ func (s *FullNodeStub) ChainGetBlockMessages(p0 context.Context, p1 cid.Cid) (*B
return nil, ErrNotSupported
}
func (s *FullNodeStruct) ChainGetEvents(p0 context.Context, p1 cid.Cid) ([]types.Event, error) {
if s.Internal.ChainGetEvents == nil {
return *new([]types.Event), ErrNotSupported
}
return s.Internal.ChainGetEvents(p0, p1)
}
func (s *FullNodeStub) ChainGetEvents(p0 context.Context, p1 cid.Cid) ([]types.Event, error) {
return *new([]types.Event), ErrNotSupported
}
func (s *FullNodeStruct) ChainGetGenesis(p0 context.Context) (*types.TipSet, error) {
if s.Internal.ChainGetGenesis == nil {
return nil, ErrNotSupported
@ -1795,6 +1941,347 @@ func (s *FullNodeStub) CreateBackup(p0 context.Context, p1 string) error {
return ErrNotSupported
}
func (s *FullNodeStruct) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) {
if s.Internal.EthAccounts == nil {
return *new([]ethtypes.EthAddress), ErrNotSupported
}
return s.Internal.EthAccounts(p0)
}
func (s *FullNodeStub) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) {
return *new([]ethtypes.EthAddress), ErrNotSupported
}
func (s *FullNodeStruct) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthBlockNumber == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthBlockNumber(p0)
}
func (s *FullNodeStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) {
if s.Internal.EthCall == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthCall(p0, p1, p2)
}
func (s *FullNodeStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *FullNodeStruct) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthChainId == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthChainId(p0)
}
func (s *FullNodeStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) {
if s.Internal.EthEstimateGas == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthEstimateGas(p0, p1)
}
func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) {
if s.Internal.EthFeeHistory == nil {
return *new(ethtypes.EthFeeHistory), ErrNotSupported
}
return s.Internal.EthFeeHistory(p0, p1, p2, p3)
}
func (s *FullNodeStub) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) {
return *new(ethtypes.EthFeeHistory), ErrNotSupported
}
func (s *FullNodeStruct) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthGasPrice == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthGasPrice(p0)
}
func (s *FullNodeStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *FullNodeStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) {
if s.Internal.EthGetBalance == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthGetBalance(p0, p1, p2)
}
func (s *FullNodeStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *FullNodeStruct) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) {
if s.Internal.EthGetBlockByHash == nil {
return *new(ethtypes.EthBlock), ErrNotSupported
}
return s.Internal.EthGetBlockByHash(p0, p1, p2)
}
func (s *FullNodeStub) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) {
return *new(ethtypes.EthBlock), ErrNotSupported
}
func (s *FullNodeStruct) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) {
if s.Internal.EthGetBlockByNumber == nil {
return *new(ethtypes.EthBlock), ErrNotSupported
}
return s.Internal.EthGetBlockByNumber(p0, p1, p2)
}
func (s *FullNodeStub) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) {
return *new(ethtypes.EthBlock), ErrNotSupported
}
func (s *FullNodeStruct) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) {
if s.Internal.EthGetBlockTransactionCountByHash == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetBlockTransactionCountByHash(p0, p1)
}
func (s *FullNodeStub) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) {
if s.Internal.EthGetBlockTransactionCountByNumber == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetBlockTransactionCountByNumber(p0, p1)
}
func (s *FullNodeStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) {
if s.Internal.EthGetCode == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthGetCode(p0, p1, p2)
}
func (s *FullNodeStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *FullNodeStruct) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetFilterChanges == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetFilterChanges(p0, p1)
}
func (s *FullNodeStub) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetFilterLogs == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetFilterLogs(p0, p1)
}
func (s *FullNodeStub) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetLogs == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetLogs(p0, p1)
}
func (s *FullNodeStub) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
if s.Internal.EthGetStorageAt == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthGetStorageAt(p0, p1, p2, p3)
}
func (s *FullNodeStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockHashAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockHashAndIndex(p0, p1, p2)
}
func (s *FullNodeStub) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockNumberAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockNumberAndIndex(p0, p1, p2)
}
func (s *FullNodeStub) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByHash == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionByHash(p0, p1)
}
func (s *FullNodeStub) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetTransactionCount(p0, p1, p2)
}
func (s *FullNodeStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) {
if s.Internal.EthGetTransactionReceipt == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionReceipt(p0, p1)
}
func (s *FullNodeStub) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthMaxPriorityFeePerGas == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthMaxPriorityFeePerGas(p0)
}
func (s *FullNodeStub) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *FullNodeStruct) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewBlockFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewBlockFilter(p0)
}
func (s *FullNodeStub) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *FullNodeStruct) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewFilter(p0, p1)
}
func (s *FullNodeStub) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *FullNodeStruct) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewPendingTransactionFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewPendingTransactionFilter(p0)
}
func (s *FullNodeStub) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *FullNodeStruct) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthProtocolVersion == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthProtocolVersion(p0)
}
func (s *FullNodeStub) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *FullNodeStruct) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) {
if s.Internal.EthSendRawTransaction == nil {
return *new(ethtypes.EthHash), ErrNotSupported
}
return s.Internal.EthSendRawTransaction(p0, p1)
}
func (s *FullNodeStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) {
return *new(ethtypes.EthHash), ErrNotSupported
}
func (s *FullNodeStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
if s.Internal.EthSubscribe == nil {
return nil, ErrNotSupported
}
return s.Internal.EthSubscribe(p0, p1, p2)
}
func (s *FullNodeStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
return nil, ErrNotSupported
}
func (s *FullNodeStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
if s.Internal.EthUninstallFilter == nil {
return false, ErrNotSupported
}
return s.Internal.EthUninstallFilter(p0, p1)
}
func (s *FullNodeStub) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
return false, ErrNotSupported
}
func (s *FullNodeStruct) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) {
if s.Internal.EthUnsubscribe == nil {
return false, ErrNotSupported
}
return s.Internal.EthUnsubscribe(p0, p1)
}
func (s *FullNodeStub) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) {
return false, ErrNotSupported
}
func (s *FullNodeStruct) GasEstimateFeeCap(p0 context.Context, p1 *types.Message, p2 int64, p3 types.TipSetKey) (types.BigInt, error) {
if s.Internal.GasEstimateFeeCap == nil {
return *new(types.BigInt), ErrNotSupported
@ -2279,6 +2766,28 @@ func (s *FullNodeStub) MsigSwapPropose(p0 context.Context, p1 address.Address, p
return nil, ErrNotSupported
}
func (s *FullNodeStruct) NetListening(p0 context.Context) (bool, error) {
if s.Internal.NetListening == nil {
return false, ErrNotSupported
}
return s.Internal.NetListening(p0)
}
func (s *FullNodeStub) NetListening(p0 context.Context) (bool, error) {
return false, ErrNotSupported
}
func (s *FullNodeStruct) NetVersion(p0 context.Context) (string, error) {
if s.Internal.NetVersion == nil {
return "", ErrNotSupported
}
return s.Internal.NetVersion(p0)
}
func (s *FullNodeStub) NetVersion(p0 context.Context) (string, error) {
return "", ErrNotSupported
}
func (s *FullNodeStruct) NodeStatus(p0 context.Context, p1 bool) (NodeStatus, error) {
if s.Internal.NodeStatus == nil {
return *new(NodeStatus), ErrNotSupported
@ -3566,6 +4075,347 @@ func (s *GatewayStub) Discover(p0 context.Context) (apitypes.OpenRPCDocument, er
return *new(apitypes.OpenRPCDocument), ErrNotSupported
}
func (s *GatewayStruct) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) {
if s.Internal.EthAccounts == nil {
return *new([]ethtypes.EthAddress), ErrNotSupported
}
return s.Internal.EthAccounts(p0)
}
func (s *GatewayStub) EthAccounts(p0 context.Context) ([]ethtypes.EthAddress, error) {
return *new([]ethtypes.EthAddress), ErrNotSupported
}
func (s *GatewayStruct) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthBlockNumber == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthBlockNumber(p0)
}
func (s *GatewayStub) EthBlockNumber(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) {
if s.Internal.EthCall == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthCall(p0, p1, p2)
}
func (s *GatewayStub) EthCall(p0 context.Context, p1 ethtypes.EthCall, p2 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *GatewayStruct) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthChainId == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthChainId(p0)
}
func (s *GatewayStub) EthChainId(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) {
if s.Internal.EthEstimateGas == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthEstimateGas(p0, p1)
}
func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) {
if s.Internal.EthFeeHistory == nil {
return *new(ethtypes.EthFeeHistory), ErrNotSupported
}
return s.Internal.EthFeeHistory(p0, p1, p2, p3)
}
func (s *GatewayStub) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) {
return *new(ethtypes.EthFeeHistory), ErrNotSupported
}
func (s *GatewayStruct) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthGasPrice == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthGasPrice(p0)
}
func (s *GatewayStub) EthGasPrice(p0 context.Context) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *GatewayStruct) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) {
if s.Internal.EthGetBalance == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthGetBalance(p0, p1, p2)
}
func (s *GatewayStub) EthGetBalance(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *GatewayStruct) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) {
if s.Internal.EthGetBlockByHash == nil {
return *new(ethtypes.EthBlock), ErrNotSupported
}
return s.Internal.EthGetBlockByHash(p0, p1, p2)
}
func (s *GatewayStub) EthGetBlockByHash(p0 context.Context, p1 ethtypes.EthHash, p2 bool) (ethtypes.EthBlock, error) {
return *new(ethtypes.EthBlock), ErrNotSupported
}
func (s *GatewayStruct) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) {
if s.Internal.EthGetBlockByNumber == nil {
return *new(ethtypes.EthBlock), ErrNotSupported
}
return s.Internal.EthGetBlockByNumber(p0, p1, p2)
}
func (s *GatewayStub) EthGetBlockByNumber(p0 context.Context, p1 string, p2 bool) (ethtypes.EthBlock, error) {
return *new(ethtypes.EthBlock), ErrNotSupported
}
func (s *GatewayStruct) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) {
if s.Internal.EthGetBlockTransactionCountByHash == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetBlockTransactionCountByHash(p0, p1)
}
func (s *GatewayStub) EthGetBlockTransactionCountByHash(p0 context.Context, p1 ethtypes.EthHash) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) {
if s.Internal.EthGetBlockTransactionCountByNumber == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetBlockTransactionCountByNumber(p0, p1)
}
func (s *GatewayStub) EthGetBlockTransactionCountByNumber(p0 context.Context, p1 ethtypes.EthUint64) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) {
if s.Internal.EthGetCode == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthGetCode(p0, p1, p2)
}
func (s *GatewayStub) EthGetCode(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *GatewayStruct) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetFilterChanges == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetFilterChanges(p0, p1)
}
func (s *GatewayStub) EthGetFilterChanges(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetFilterLogs == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetFilterLogs(p0, p1)
}
func (s *GatewayStub) EthGetFilterLogs(p0 context.Context, p1 ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
if s.Internal.EthGetLogs == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetLogs(p0, p1)
}
func (s *GatewayStub) EthGetLogs(p0 context.Context, p1 *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
if s.Internal.EthGetStorageAt == nil {
return *new(ethtypes.EthBytes), ErrNotSupported
}
return s.Internal.EthGetStorageAt(p0, p1, p2, p3)
}
func (s *GatewayStub) EthGetStorageAt(p0 context.Context, p1 ethtypes.EthAddress, p2 ethtypes.EthBytes, p3 string) (ethtypes.EthBytes, error) {
return *new(ethtypes.EthBytes), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockHashAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockHashAndIndex(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionByBlockHashAndIndex(p0 context.Context, p1 ethtypes.EthHash, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByBlockNumberAndIndex == nil {
return *new(ethtypes.EthTx), ErrNotSupported
}
return s.Internal.EthGetTransactionByBlockNumberAndIndex(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionByBlockNumberAndIndex(p0 context.Context, p1 ethtypes.EthUint64, p2 ethtypes.EthUint64) (ethtypes.EthTx, error) {
return *new(ethtypes.EthTx), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
if s.Internal.EthGetTransactionByHash == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionByHash(p0, p1)
}
func (s *GatewayStub) EthGetTransactionByHash(p0 context.Context, p1 *ethtypes.EthHash) (*ethtypes.EthTx, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
if s.Internal.EthGetTransactionCount == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthGetTransactionCount(p0, p1, p2)
}
func (s *GatewayStub) EthGetTransactionCount(p0 context.Context, p1 ethtypes.EthAddress, p2 string) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) {
if s.Internal.EthGetTransactionReceipt == nil {
return nil, ErrNotSupported
}
return s.Internal.EthGetTransactionReceipt(p0, p1)
}
func (s *GatewayStub) EthGetTransactionReceipt(p0 context.Context, p1 ethtypes.EthHash) (*EthTxReceipt, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
if s.Internal.EthMaxPriorityFeePerGas == nil {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
return s.Internal.EthMaxPriorityFeePerGas(p0)
}
func (s *GatewayStub) EthMaxPriorityFeePerGas(p0 context.Context) (ethtypes.EthBigInt, error) {
return *new(ethtypes.EthBigInt), ErrNotSupported
}
func (s *GatewayStruct) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewBlockFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewBlockFilter(p0)
}
func (s *GatewayStub) EthNewBlockFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *GatewayStruct) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewFilter(p0, p1)
}
func (s *GatewayStub) EthNewFilter(p0 context.Context, p1 *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *GatewayStruct) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
if s.Internal.EthNewPendingTransactionFilter == nil {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
return s.Internal.EthNewPendingTransactionFilter(p0)
}
func (s *GatewayStub) EthNewPendingTransactionFilter(p0 context.Context) (ethtypes.EthFilterID, error) {
return *new(ethtypes.EthFilterID), ErrNotSupported
}
func (s *GatewayStruct) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) {
if s.Internal.EthProtocolVersion == nil {
return *new(ethtypes.EthUint64), ErrNotSupported
}
return s.Internal.EthProtocolVersion(p0)
}
func (s *GatewayStub) EthProtocolVersion(p0 context.Context) (ethtypes.EthUint64, error) {
return *new(ethtypes.EthUint64), ErrNotSupported
}
func (s *GatewayStruct) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) {
if s.Internal.EthSendRawTransaction == nil {
return *new(ethtypes.EthHash), ErrNotSupported
}
return s.Internal.EthSendRawTransaction(p0, p1)
}
func (s *GatewayStub) EthSendRawTransaction(p0 context.Context, p1 ethtypes.EthBytes) (ethtypes.EthHash, error) {
return *new(ethtypes.EthHash), ErrNotSupported
}
func (s *GatewayStruct) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
if s.Internal.EthSubscribe == nil {
return nil, ErrNotSupported
}
return s.Internal.EthSubscribe(p0, p1, p2)
}
func (s *GatewayStub) EthSubscribe(p0 context.Context, p1 string, p2 *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
return nil, ErrNotSupported
}
func (s *GatewayStruct) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
if s.Internal.EthUninstallFilter == nil {
return false, ErrNotSupported
}
return s.Internal.EthUninstallFilter(p0, p1)
}
func (s *GatewayStub) EthUninstallFilter(p0 context.Context, p1 ethtypes.EthFilterID) (bool, error) {
return false, ErrNotSupported
}
func (s *GatewayStruct) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) {
if s.Internal.EthUnsubscribe == nil {
return false, ErrNotSupported
}
return s.Internal.EthUnsubscribe(p0, p1)
}
func (s *GatewayStub) EthUnsubscribe(p0 context.Context, p1 ethtypes.EthSubscriptionID) (bool, error) {
return false, ErrNotSupported
}
func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) {
if s.Internal.GasEstimateMessageGas == nil {
return nil, ErrNotSupported
@ -3632,6 +4482,28 @@ func (s *GatewayStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Addr
return *new(MsigVesting), ErrNotSupported
}
func (s *GatewayStruct) NetListening(p0 context.Context) (bool, error) {
if s.Internal.NetListening == nil {
return false, ErrNotSupported
}
return s.Internal.NetListening(p0)
}
func (s *GatewayStub) NetListening(p0 context.Context) (bool, error) {
return false, ErrNotSupported
}
func (s *GatewayStruct) NetVersion(p0 context.Context) (string, error) {
if s.Internal.NetVersion == nil {
return "", ErrNotSupported
}
return s.Internal.NetVersion(p0)
}
func (s *GatewayStub) NetVersion(p0 context.Context) (string, error) {
return "", ErrNotSupported
}
func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) {
if s.Internal.StateAccountKey == nil {
return *new(address.Address), ErrNotSupported
@ -4182,15 +5054,15 @@ func (s *StorageMinerStub) ComputeDataCid(p0 context.Context, p1 abi.UnpaddedPie
return *new(abi.PieceInfo), ErrNotSupported
}
func (s *StorageMinerStruct) ComputeProof(p0 context.Context, p1 []builtin.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtin.PoStProof, error) {
func (s *StorageMinerStruct) ComputeProof(p0 context.Context, p1 []builtinactors.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtinactors.PoStProof, error) {
if s.Internal.ComputeProof == nil {
return *new([]builtin.PoStProof), ErrNotSupported
return *new([]builtinactors.PoStProof), ErrNotSupported
}
return s.Internal.ComputeProof(p0, p1, p2, p3, p4)
}
func (s *StorageMinerStub) ComputeProof(p0 context.Context, p1 []builtin.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtin.PoStProof, error) {
return *new([]builtin.PoStProof), ErrNotSupported
func (s *StorageMinerStub) ComputeProof(p0 context.Context, p1 []builtinactors.ExtendedSectorInfo, p2 abi.PoStRandomness, p3 abi.ChainEpoch, p4 abinetwork.Version) ([]builtinactors.PoStProof, error) {
return *new([]builtinactors.PoStProof), ErrNotSupported
}
func (s *StorageMinerStruct) ComputeWindowPoSt(p0 context.Context, p1 uint64, p2 types.TipSetKey) ([]miner.SubmitWindowedPoStParams, error) {

View File

@ -338,6 +338,7 @@ type ForkUpgradeParams struct {
UpgradeOhSnapHeight abi.ChainEpoch
UpgradeSkyrHeight abi.ChainEpoch
UpgradeSharkHeight abi.ChainEpoch
UpgradeHyggeHeight abi.ChainEpoch
}
type NonceMapType map[address.Address]uint64

5
api/types/rpc.go Normal file
View File

@ -0,0 +1,5 @@
package apitypes
type Aliaser interface {
AliasMethod(alias, original string)
}

View File

@ -905,6 +905,10 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
walkCnt := new(int64)
scanCnt := new(int64)
tsRef := func(blkCids []cid.Cid) (cid.Cid, error) {
return types.NewTipSetKey(blkCids...).Cid()
}
stopWalk := func(_ cid.Cid) error { return errStopWalk }
walkBlock := func(c cid.Cid) error {
@ -926,11 +930,19 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
err = s.view(c, func(data []byte) error {
return hdr.UnmarshalCBOR(bytes.NewBuffer(data))
})
if err != nil {
return xerrors.Errorf("error unmarshaling block header (cid: %s): %w", c, err)
}
// tipset CID references are retained
pRef, err := tsRef(hdr.Parents)
if err != nil {
return xerrors.Errorf("error computing cid reference to parent tipset")
}
if err := s.walkObjectIncomplete(pRef, visitor, fHot, stopWalk); err != nil {
return xerrors.Errorf("error walking parent tipset cid reference")
}
// message are retained if within the inclMsgs boundary
if hdr.Height >= inclMsgs && hdr.Height > 0 {
if inclMsgs < inclState {
@ -981,6 +993,15 @@ func (s *SplitStore) walkChain(ts *types.TipSet, inclState, inclMsgs abi.ChainEp
return nil
}
// retain ref to chain head
hRef, err := tsRef(ts.Cids())
if err != nil {
return xerrors.Errorf("error computing cid reference to parent tipset")
}
if err := s.walkObjectIncomplete(hRef, visitor, fHot, stopWalk); err != nil {
return xerrors.Errorf("error walking parent tipset cid reference")
}
for len(toWalk) > 0 {
// walking can take a while, so check this with every opportunity
if err := s.checkClosing(); err != nil {

View File

@ -1,6 +1,6 @@
#!/bin/bash
NETWORKS=(devnet mainnet caterpillarnet butterflynet testing testing-fake-proofs calibrationnet)
NETWORKS=(devnet mainnet caterpillarnet butterflynet testing testing-fake-proofs calibrationnet hyperspace)
set -e

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,4 @@
/dns4/de0.bootstrap.wallaby.network/tcp/1337/p2p/12D3KooWHAvUVk5XuxSwi2dNLWbTDDRSGeHxMuWdQ3SQpRuNHbLz
/dns4/de1.bootstrap.wallaby.network/tcp/1337/p2p/12D3KooWBRqtxhJCtiLmCwKgAQozJtdGinEDdJGoS5oHw7vCjMGc
/dns4/ca0.bootstrap.wallaby.network/tcp/1337/p2p/12D3KooWCApBpUk7EX9pmEfyky1gKC6N2KJ74S1AwFfvnkDqw3pK
/dns4/sg0.bootstrap.wallaby.network/tcp/1337/p2p/12D3KooWLnYqr4hRoNHBJQVXsFGkDoKuoVfw5R2ASw1bHzrWU5Px

View File

@ -9,58 +9,68 @@ import (
var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMetadata{{
Network: "butterflynet",
Version: 8,
ManifestCid: MustParseCid("bafy2bzacedvaarfyh6q3bk4dyzux46ednlace2ckxp5nbyn6mb3da2apqn6sk"),
ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceavzeu4gqte7o33vr4htiaapiwpfq6p26tgdkqla2baqhmiqswfso"),
"cron": MustParseCid("bafk2bzacech35onpqxep4yox36k7sr4mj4bch54s3i4b3yyaustrbo5xwfbfs"),
"init": MustParseCid("bafk2bzaceahxin3sf5f6ude5j6we4yeqlg66s5qe4tu7lwp26jcg7yp2ns6hi"),
"multisig": MustParseCid("bafk2bzacectfmzjtniypgl4whm42sws5aupihqgfikwsr7p5yoq3bmqaogldi"),
"paymentchannel": MustParseCid("bafk2bzacecbwu54ce5mjgp2pqxyj6kpn2vlgiu5wv2lj2byjiegxnn3infd5i"),
"reward": MustParseCid("bafk2bzacecskkbhe6c4ud5jt62wg4w7j7shj6xdwoyic74s5y6pgywxxvnw72"),
"storagemarket": MustParseCid("bafk2bzacebycxcwwm7hwhuhpasaskil2kxaqb7tins7azdvvm72rorlciuysi"),
"storageminer": MustParseCid("bafk2bzacecgx3etor5m6lahpmjdwqnryutqe6naiurfhgsju72rd4nqssutbg"),
"storagepower": MustParseCid("bafk2bzaceayvy6xyp5cwtngm457c5hssvihidppgq3o7gy3dlmhgor3yzujoc"),
"system": MustParseCid("bafk2bzacec6xctjxybp7r3kkhase56o6jsaiua7ure5ttu2xfuojt4jhlsoa6"),
"verifiedregistry": MustParseCid("bafk2bzacec2hcqlqcfacylfcrhhliwkisvh4y3adwt47xkf2gdvodwu6ccepc"),
"account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"),
"cron": MustParseCid("bafk2bzacecrszortqkc7har77ssgajglymv6ftrqvmdko5h2yqqh5k2qospl2"),
"datacap": MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e"),
"eam": MustParseCid("bafk2bzacecflry2dyjqj6fhpovkbcbei377zabectznuxsf6bxggsve7bsxga"),
"ethaccount": MustParseCid("bafk2bzacedl4pmkfxkzoqajs6im3ranmopozsmxjcxsnk3kwvd3vv7mfwwrf4"),
"evm": MustParseCid("bafk2bzacebgzvmvwv7rsnnhp3zhqbiqkumvyrc7pazfovpptgpgtqkalrli74"),
"init": MustParseCid("bafk2bzacecbxp66q3ytjkg37nyv4rmzezbfaigvx4i5yhvqbm5gg4amjeaias"),
"multisig": MustParseCid("bafk2bzacecjltag3mn75dsnmrmopjow27buxqhabissowayqlmavrcfetqswc"),
"paymentchannel": MustParseCid("bafk2bzacednzxg263eqbl2imwz3uhujov63tjkffieyl4hl3dhrgxyhwep6hc"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacectp23cxsbbdrr3uggnw7f263qll5wkkfzqhn5yq37ae2ehdjdzri"),
"storagemarket": MustParseCid("bafk2bzacea45ko3ezkpeujsniovncwnizc4wsxd7kyckskhs7gvzwthzb2mqe"),
"storageminer": MustParseCid("bafk2bzaced74qthwrl3gahcf7o3vrdrodbcqhlplh6fykbgy5sd2iyouhq44c"),
"storagepower": MustParseCid("bafk2bzaceduksv6wqthr5fgp7mx5prv6gzul2oozf3svrjbuggc4bgokdxgfy"),
"system": MustParseCid("bafk2bzacebe6j2ius6clbbr7dypsg54jzmn5xablzunph7ebedw6yhwla4cj2"),
"verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"),
},
}, {
Network: "butterflynet",
Version: 9,
ManifestCid: MustParseCid("bafy2bzacec35by4erhcdgcsgzp7yb3j57utydlxxfc73m3k5pep67ehvvyv6i"),
ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceajsdln7v4chxqoukiw7lxw6aexg5qdsaex2hgelz2sbu24iblhzg"),
"cron": MustParseCid("bafk2bzacecgrwmgnqhybn3l23uvwf2n2vrcfjrprfzgd44uxers2pgr5mhsue"),
"datacap": MustParseCid("bafk2bzacebyier2ceh27acbrq2ccv4efvzotl6qntnlrxdsrik6i4tembz6qw"),
"init": MustParseCid("bafk2bzaceberhto43wnf4pklkd4c7d36kzslngyzyms4op7shxuswv3dtvfxu"),
"multisig": MustParseCid("bafk2bzaceaclpbrhoqdruvsuqqgknvy2k5dywzmjoehk4uarce3uvt3w2rewu"),
"paymentchannel": MustParseCid("bafk2bzacedzp56g5cg73oilloak3kf7u667rdkd5pgnhe2cljmr3o7ykcrzuk"),
"reward": MustParseCid("bafk2bzacebczbwfbbi6mvppbjcozatasjiaohvjjiqcy65ccuuyyw3xiixhk2"),
"storagemarket": MustParseCid("bafk2bzaceawqexy6t2ybzh3jjwhbs7icbg5vqnedbbge4e4r4pfp7spkcadsu"),
"storageminer": MustParseCid("bafk2bzacearemd7pn2jj26fdtqd4di27lfhpng3vp5chepm7qnmdzgiqr6wfi"),
"storagepower": MustParseCid("bafk2bzaceddc7fiaxfobfegqaobf5xinjgmhsa5iu4yi6klvc3jmjimcdvgyg"),
"system": MustParseCid("bafk2bzacedylltr57b2n6zpadh4i2c2kis4fzzvhao3kgvfaggrrbqyacew7q"),
"verifiedregistry": MustParseCid("bafk2bzacecjkesz766626ab4svnzpq3jfs26a75vfktlfaku5fjdao2eyiqyq"),
"account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"),
"cron": MustParseCid("bafk2bzacecrszortqkc7har77ssgajglymv6ftrqvmdko5h2yqqh5k2qospl2"),
"datacap": MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e"),
"eam": MustParseCid("bafk2bzacecflry2dyjqj6fhpovkbcbei377zabectznuxsf6bxggsve7bsxga"),
"ethaccount": MustParseCid("bafk2bzacedl4pmkfxkzoqajs6im3ranmopozsmxjcxsnk3kwvd3vv7mfwwrf4"),
"evm": MustParseCid("bafk2bzacebgzvmvwv7rsnnhp3zhqbiqkumvyrc7pazfovpptgpgtqkalrli74"),
"init": MustParseCid("bafk2bzacecbxp66q3ytjkg37nyv4rmzezbfaigvx4i5yhvqbm5gg4amjeaias"),
"multisig": MustParseCid("bafk2bzacecjltag3mn75dsnmrmopjow27buxqhabissowayqlmavrcfetqswc"),
"paymentchannel": MustParseCid("bafk2bzacednzxg263eqbl2imwz3uhujov63tjkffieyl4hl3dhrgxyhwep6hc"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacectp23cxsbbdrr3uggnw7f263qll5wkkfzqhn5yq37ae2ehdjdzri"),
"storagemarket": MustParseCid("bafk2bzacea45ko3ezkpeujsniovncwnizc4wsxd7kyckskhs7gvzwthzb2mqe"),
"storageminer": MustParseCid("bafk2bzaced74qthwrl3gahcf7o3vrdrodbcqhlplh6fykbgy5sd2iyouhq44c"),
"storagepower": MustParseCid("bafk2bzaceduksv6wqthr5fgp7mx5prv6gzul2oozf3svrjbuggc4bgokdxgfy"),
"system": MustParseCid("bafk2bzacebe6j2ius6clbbr7dypsg54jzmn5xablzunph7ebedw6yhwla4cj2"),
"verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"),
},
}, {
Network: "butterflynet",
Version: 10,
ManifestCid: MustParseCid("bafy2bzaceciz4ytt5gnn6gc4epez7v6xeg6efkgbvwfxkoa34o2gj3hp5f7zc"),
ManifestCid: MustParseCid("bafy2bzacecjs7xvhtejsh47b2tx2iwe7mbad4kxovbfs7a6wxfl47kcnl25bm"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacedavorwsriewoddjlaganjpsk3o7zfts2wyid3clv5xnctacg37j2"),
"cron": MustParseCid("bafk2bzacebtauucwaewxuzgxfpjtmn6xt3kya4om4ugyprlkhhkde76h7fkqg"),
"datacap": MustParseCid("bafk2bzacebzdjapqwasq6woxkgq2nm2nre3v7cl2754xwiuo2cfhvsceq4cba"),
"eam": MustParseCid("bafk2bzacecmr4zdbpfnemvgo446qby7x4y4v5cbfespt3f6ousv2hxnflyrlk"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzacebuewexvig54cuvsvwn4k4zr36tm2q5fel4ezq4v7363n2lmn362k"),
"init": MustParseCid("bafk2bzacebww5gsctsk5hack2alkt4kh55bmpb4ywzbyyhoaskryymjj3snj6"),
"multisig": MustParseCid("bafk2bzacec5k4wxvou34pyjd5kcsrbsfnlk4k753kkscg3ron2r7tsxollfsq"),
"paymentchannel": MustParseCid("bafk2bzacebzdeaxglaqpmegalakmxr6secjd24mu5llo4ctoy7pvom5upyuvs"),
"reward": MustParseCid("bafk2bzaceb4hyabxnyrrsno5erqqwk5ynnjibblzfcaq3aotlz3ek4uu6dyla"),
"storagemarket": MustParseCid("bafk2bzacedpocbf2lg2x2jg6arw2argnwmvo2hyjqvpkrgfu4khz5mtlzxz2o"),
"storageminer": MustParseCid("bafk2bzaceacrumah7jdfc62bmvemob4lsh5yiohwodest2cgxakgnn24cenlk"),
"storagepower": MustParseCid("bafk2bzaceaxz6n5nywermfptnz6dc53vqsa42lic4rf66l4irm3mqfj4ak5ps"),
"system": MustParseCid("bafk2bzaceb4w5bblgyu25ylytpmfrixjsk2ra6emd44j4mv42xfxbwnqloyzi"),
"verifiedregistry": MustParseCid("bafk2bzacedbz2koeb6teewobcjdpgfv7qdae7utgoka6wzlkf6gronnis2nn2"),
"account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"),
"cron": MustParseCid("bafk2bzacecrszortqkc7har77ssgajglymv6ftrqvmdko5h2yqqh5k2qospl2"),
"datacap": MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e"),
"eam": MustParseCid("bafk2bzaceavdyeveel5iohjg7t6twc2cbdo7bt3m5xajwtibekudyhzv2xojy"),
"ethaccount": MustParseCid("bafk2bzacedl4pmkfxkzoqajs6im3ranmopozsmxjcxsnk3kwvd3vv7mfwwrf4"),
"evm": MustParseCid("bafk2bzacebgzvmvwv7rsnnhp3zhqbiqkumvyrc7pazfovpptgpgtqkalrli74"),
"init": MustParseCid("bafk2bzacecbxp66q3ytjkg37nyv4rmzezbfaigvx4i5yhvqbm5gg4amjeaias"),
"multisig": MustParseCid("bafk2bzacecjltag3mn75dsnmrmopjow27buxqhabissowayqlmavrcfetqswc"),
"paymentchannel": MustParseCid("bafk2bzacednzxg263eqbl2imwz3uhujov63tjkffieyl4hl3dhrgxyhwep6hc"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacectp23cxsbbdrr3uggnw7f263qll5wkkfzqhn5yq37ae2ehdjdzri"),
"storagemarket": MustParseCid("bafk2bzacea45ko3ezkpeujsniovncwnizc4wsxd7kyckskhs7gvzwthzb2mqe"),
"storageminer": MustParseCid("bafk2bzaced74qthwrl3gahcf7o3vrdrodbcqhlplh6fykbgy5sd2iyouhq44c"),
"storagepower": MustParseCid("bafk2bzaceduksv6wqthr5fgp7mx5prv6gzul2oozf3svrjbuggc4bgokdxgfy"),
"system": MustParseCid("bafk2bzacebe6j2ius6clbbr7dypsg54jzmn5xablzunph7ebedw6yhwla4cj2"),
"verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"),
},
}, {
Network: "calibrationnet",
@ -100,79 +110,90 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, {
Network: "calibrationnet",
Version: 10,
ManifestCid: MustParseCid("bafy2bzaced7wbd43lvgc55xb37mkoo4ppev6ig4jj4j7dtswtjfjq4u5qmpck"),
ManifestCid: MustParseCid("bafy2bzaceaklxgrzd34i53rm4eeq6477nlq2ckpex27evftbsmjd2yrdbj4ba"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecq4owv5begvryvpsy4atfb2jnf7g7o4hxovtdb5a4jfkzacownli"),
"cron": MustParseCid("bafk2bzaced4uz5w5h5wksx4end27lphd4qc4kh7q336uyt46lba5ddynwftya"),
"datacap": MustParseCid("bafk2bzacedoc7y4s5n3p2zo4bcmafcrellkakn2e3uyf5wb3mtbuqhvwqn2l4"),
"eam": MustParseCid("bafk2bzacealpqjgz5qmucm3v6z6hn36igx7zijixhqrxwoj3g4bdgvyml3adi"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzacedmlmyy2efbt4qk5ighawiychklhzc6pzyiwvpijwvxoq3xyxlgxw"),
"init": MustParseCid("bafk2bzaceaqcfmfylwdemq5bdcelydpf6iqfct4p7b2zwtmqyhuxn522yvic2"),
"multisig": MustParseCid("bafk2bzacebuh55hkbkobmmoaoduruss5nsh6e2gtqtdbqsmw6e7k5vg6heyrm"),
"paymentchannel": MustParseCid("bafk2bzacedcpzw7prdoxnaclcvmtwr6yf54zi4bzzwe5w3xknh72ji6p3qfc6"),
"reward": MustParseCid("bafk2bzaced74ym6j424zzbr6millasfcyl3r4zm5fnauasrwn3ti6fdarbkym"),
"storagemarket": MustParseCid("bafk2bzacec7delr2q42yj4wu3daa5xjz4zezeivphtx3xwyvpgwpdnfoevhh2"),
"storageminer": MustParseCid("bafk2bzaced7isnew5lhu237pdtwaqmbv65qqvfmmnve2c5yfobtfqw2fptuvc"),
"storagepower": MustParseCid("bafk2bzacebe5frk6gcgzcvzkxavhhbs3id3iyacybn7y7gxwzgl5t6zawzswg"),
"system": MustParseCid("bafk2bzacectivaezqijucle5s2f7xeui5uxig7bnk7fe4vsvz3xu7agjtb2ge"),
"verifiedregistry": MustParseCid("bafk2bzaceczgwckte4exultjxyzgzoo6m6r5coyphnlappi4clethhhybslxc"),
"account": MustParseCid("bafk2bzacea7zmrdz2rjbzlbmrmx3ko6pm3cbyqxxgogiqldsccbqffuok7m6s"),
"cron": MustParseCid("bafk2bzacec7bxugi7ouh75nglycy7qwdq7e2hnku3w6yafq4fwdwvvq2mtrl2"),
"datacap": MustParseCid("bafk2bzacedii4stmlo3ccdff7eevcolmgnuxy5ftkzbzwtkqa4iinlfzq4mei"),
"eam": MustParseCid("bafk2bzacea6du2tjdewnfd2zofjp342d2lw7rdl6hx4ejawup744kpym2xsf4"),
"ethaccount": MustParseCid("bafk2bzacecgbcbh3uk7olcfdqo44no5nxxayeqnycdznrlekqigbifor2revm"),
"evm": MustParseCid("bafk2bzaceanxhvz5czs6xfunhbysbttmim5e7poftibsu53uqn4by5nqmdaj6"),
"init": MustParseCid("bafk2bzacea7lxnvgxupwwgoxlmwtrca75w73qabe324wnwx43qranbgf5zdqo"),
"multisig": MustParseCid("bafk2bzacear5eu5gpbjlroqkmsgpqerzc4aemp2uqcaeq7s2h4ur4ucgpzesg"),
"paymentchannel": MustParseCid("bafk2bzacecwxuruxawcru7xfcx3rmt4hmhlfh4hi6jvfumerazz6jpvfmxxcw"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebk4syfvyk7kbxelk7ajo4vuxcc24k5ry52mvi3qtadlucy2vqlay"),
"storagemarket": MustParseCid("bafk2bzaced2rfzwup3jlwovblx2y7q64w6mshbtn2nmampi4zfd3b4oplkp5c"),
"storageminer": MustParseCid("bafk2bzacecden66gfmmgylmr47myn4murqmbt3ycyxqayn54yzhcsda32rp3m"),
"storagepower": MustParseCid("bafk2bzacebxvco3shuhdnzjmmme3olbffdgpab7j3onfncksi762k3agjhzaa"),
"system": MustParseCid("bafk2bzacednnhpk5kno67bkomiohweglryqvgnqz4cbks6eomidai677fat5w"),
"verifiedregistry": MustParseCid("bafk2bzaceawecz24xbz7robn7ck7k2mprkewvup6q346whbfiybcrvy63qcsa"),
},
}, {
Network: "caterpillarnet",
Version: 8,
ManifestCid: MustParseCid("bafy2bzacecsmunz6fzhg53276cixadn6ybhcnzkgbw3la5hf342tfxsdoet26"),
ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaced6yatl4y2nmqmx2h3btk3np6oelyw2yt57elsb2nfmm33fadzt2g"),
"cron": MustParseCid("bafk2bzacebrujytq4u7g62jbz52gio5k2s6rhruty7nt4eqq7ygitzxuee5zi"),
"init": MustParseCid("bafk2bzacedajw5ptnwfdidv6m4rvd4c2m7dve4lhfbawygl5idkalcxbiiudu"),
"multisig": MustParseCid("bafk2bzaceb3kh5hjh6eebb5236xp7crn2owyyo7irap6sy4ns76uc7om6pxuy"),
"paymentchannel": MustParseCid("bafk2bzacedl5am53e4mtxpzligcycxvmkolfkhfiuavww2dq3ukgaqwowj7vw"),
"reward": MustParseCid("bafk2bzacecbswf242j43cymj3wh7nszawwlofv6z6z4qipb5d32hpxdhxywng"),
"storagemarket": MustParseCid("bafk2bzaceca5ersmg3zxf2cztgktq33bmfjuiqjcjlktwj52xyrpujbdsqvek"),
"storageminer": MustParseCid("bafk2bzacedg2fqaq5udfp3h6cxhywm27dgagxtselfgkyyyunqq362eaxpdm4"),
"storagepower": MustParseCid("bafk2bzaceb3dm2i2q323e6iozo3r6pyded645vvlpf537kga2a3hu5x7abgl4"),
"system": MustParseCid("bafk2bzacebu47th3xerlngqavlipb6cfu2utljkxxzgadc3totogto2tmx2jc"),
"verifiedregistry": MustParseCid("bafk2bzaceci3niq3rmbcmepgn27zvlgci6d5t4dvthx3pbmmx3wcu5elova6i"),
"account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"),
"cron": MustParseCid("bafk2bzaceaganmlpozvy4jywigs46pfrtdmhjjey6uyhpurplqbasojsislba"),
"datacap": MustParseCid("bafk2bzacebafqqe3wv5ytkfwmqzbmchgem66pw6yq6rl7w6vlhqsbkxnisswq"),
"eam": MustParseCid("bafk2bzaceaeayeksiivw4y3gdqtigbgfntyvwc3q7v2ivb5kx7u55pn4q5lt6"),
"ethaccount": MustParseCid("bafk2bzaceburkmtd63nmzxpux5rcxsbqr6x5didl2ce7al32g4tqrvo4pjz2i"),
"evm": MustParseCid("bafk2bzacea7tp4lop7ivhay3ozitkmxxurk74v4zse42ant47rh2uw5z3tq5e"),
"init": MustParseCid("bafk2bzaced23r54kwuebl7t6mdantbby5qpfduxwxfryeliof2enyqzhokix6"),
"multisig": MustParseCid("bafk2bzacebcn3rib6j6jvclys7dkf62hco45ssgamczkrtzt6xyewd6gt3mtu"),
"paymentchannel": MustParseCid("bafk2bzacecvas4leo44pqdguj22nnwqoqdgwajzrpm5d6ltkehc37ni6p6doq"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebiizh4ohvv6p4uxjusoygex4wxcgvudqmdl2fsh6ft6s2zt4tz6q"),
"storagemarket": MustParseCid("bafk2bzacedhkidshm7w2sqlw7izvaieyhkvmyhfsem6t6qfnkh7dnwqe56po2"),
"storageminer": MustParseCid("bafk2bzacedcmsibwfwhkp3sabmbyjmhqibyhjf3wwst7u5bkb2k6xpun3xevg"),
"storagepower": MustParseCid("bafk2bzacecrgnpypxnxzgglhlitaallfee3dl4ejy3y63knl7llnwba4ycf7i"),
"system": MustParseCid("bafk2bzacecl7gizbe52xj6sfm5glubkhrdblmzuwlid6lxrwr5zhcmv4dl2ew"),
"verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"),
},
}, {
Network: "caterpillarnet",
Version: 9,
ManifestCid: MustParseCid("bafy2bzacedo6tmei6rzjaaddh2yffe5xgr6w4smnadofjhomc3saiv3ubplqe"),
ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebb32htqlwcwiotyvtbeehfmluu2ubjnepo57gelelwitudrstwba"),
"cron": MustParseCid("bafk2bzaceatvkww7soy4a6onu6xhe7pzkdzkqw46ywuu56yv3ncl76xpotzqu"),
"datacap": MustParseCid("bafk2bzaced57nk7i7w6qmbosy4gd6atme6yppesdgjllou6nppbti5yw6glcg"),
"init": MustParseCid("bafk2bzacedtoputbtz573ytg4yo5wbbg7fbhrzplux4uknxrb2jarifcuxxou"),
"multisig": MustParseCid("bafk2bzacec22z3xz45mbwgtliwkj7ngc43bervnt557c6dqsg6aesatpd5isy"),
"paymentchannel": MustParseCid("bafk2bzacedym7xnaxr2igfq72rttj2adqyqqfxk3j4qovp2bcwqk5paoe4t7e"),
"reward": MustParseCid("bafk2bzacedemsmbmbtk5toprmm6jivjq3wkxumavc65vpvm6ngspgjfkth7z6"),
"storagemarket": MustParseCid("bafk2bzacecb53mmklf4rbv263dvufqj3nsf7mi6zk2tjlgwmzbr633kw3ds3w"),
"storageminer": MustParseCid("bafk2bzacea3wljpn2ixgnd4lovr6yckiwd652ytcrz5amgj47lg6drjhgggqa"),
"storagepower": MustParseCid("bafk2bzaceakvohgvovpeldb6hjfg7readxo37a5h4qauis4nz6pte7mcll6c2"),
"system": MustParseCid("bafk2bzacecisuqj2ln7ep72xaejvs2lrgh2logc7retxxpd3qvobymwyz7bxo"),
"verifiedregistry": MustParseCid("bafk2bzacebyjosiripwqyf56yhjfs5hg26mch7totsqth4rgpt5j32hqg6ric"),
"account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"),
"cron": MustParseCid("bafk2bzaceaganmlpozvy4jywigs46pfrtdmhjjey6uyhpurplqbasojsislba"),
"datacap": MustParseCid("bafk2bzacebafqqe3wv5ytkfwmqzbmchgem66pw6yq6rl7w6vlhqsbkxnisswq"),
"eam": MustParseCid("bafk2bzaceaeayeksiivw4y3gdqtigbgfntyvwc3q7v2ivb5kx7u55pn4q5lt6"),
"ethaccount": MustParseCid("bafk2bzaceburkmtd63nmzxpux5rcxsbqr6x5didl2ce7al32g4tqrvo4pjz2i"),
"evm": MustParseCid("bafk2bzacea7tp4lop7ivhay3ozitkmxxurk74v4zse42ant47rh2uw5z3tq5e"),
"init": MustParseCid("bafk2bzaced23r54kwuebl7t6mdantbby5qpfduxwxfryeliof2enyqzhokix6"),
"multisig": MustParseCid("bafk2bzacebcn3rib6j6jvclys7dkf62hco45ssgamczkrtzt6xyewd6gt3mtu"),
"paymentchannel": MustParseCid("bafk2bzacecvas4leo44pqdguj22nnwqoqdgwajzrpm5d6ltkehc37ni6p6doq"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebiizh4ohvv6p4uxjusoygex4wxcgvudqmdl2fsh6ft6s2zt4tz6q"),
"storagemarket": MustParseCid("bafk2bzacedhkidshm7w2sqlw7izvaieyhkvmyhfsem6t6qfnkh7dnwqe56po2"),
"storageminer": MustParseCid("bafk2bzacedcmsibwfwhkp3sabmbyjmhqibyhjf3wwst7u5bkb2k6xpun3xevg"),
"storagepower": MustParseCid("bafk2bzacecrgnpypxnxzgglhlitaallfee3dl4ejy3y63knl7llnwba4ycf7i"),
"system": MustParseCid("bafk2bzacecl7gizbe52xj6sfm5glubkhrdblmzuwlid6lxrwr5zhcmv4dl2ew"),
"verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"),
},
}, {
Network: "caterpillarnet",
Version: 10,
ManifestCid: MustParseCid("bafy2bzacea5csj2os7h76a6yvf6shgpwkysawijxemk5uvvzejxrwjo6ir4yg"),
ManifestCid: MustParseCid("bafy2bzaceawh5opc4uqctlzc6xnq3pb7ycchfqwprjysbfa5xlrmiicbbvkrm"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacea7tpruyxdgyz4xa7curiphwdw4abmspft3ee24puruazdcl3tq5c"),
"cron": MustParseCid("bafk2bzacebc6kkj7kzsicm5baszjgd37b4b3kijsffqmmkhhjlyd7zhkwfcqm"),
"datacap": MustParseCid("bafk2bzaceddcmwl6po2jd3tfkkgv4zvub7i47gsx33pkqdspqhgvhe4npc4as"),
"eam": MustParseCid("bafk2bzaceccsvcww2rmqnh4plkq6oapqaeqbhydrtup54z4dwunolz5tpgtb4"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzacea5sig3zpxfkqppoj3t344cvuhzvkx6ge2isgdzc34rfpng2ogdje"),
"init": MustParseCid("bafk2bzacedtby353aho7itoyoj7w6moydmigjm3sgy6djgnfxqehlpae4vcc2"),
"multisig": MustParseCid("bafk2bzacedyguvwz5zfveqoqicn3j6lkdzipf247nhvdi6dvmahulr7nzgox6"),
"paymentchannel": MustParseCid("bafk2bzaceavaatmmnsz3v3ksopcbu6jx4iq7u7nnmqbclsiabsfkfu3zfpmka"),
"reward": MustParseCid("bafk2bzacecrphs4avteik4yejsqwkpy5bcqramdhnzykbfq3uu2qalj2p26ti"),
"storagemarket": MustParseCid("bafk2bzaceajby2jb5m3fenzarum374zxdzuyrpkspfljwovu7c3hvyceqd5sa"),
"storageminer": MustParseCid("bafk2bzacebqtn7jdvk756ighri5ajro6gjepnef3c6rxupbbgkth62zytiy5s"),
"storagepower": MustParseCid("bafk2bzacedwlo32brlalpovfkkk7qwo3ou2kpgv2bf7fioy5srn7uejmn7n46"),
"system": MustParseCid("bafk2bzacebbt63h26x5vw5fdo2pmdb4q65u3t6lilkugvmjar6zfsc7ethxsi"),
"verifiedregistry": MustParseCid("bafk2bzacecr5kbyypdxnxlepzk5sji2k72t454vto5ok4owfcuwfpeyivjtu4"),
"account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"),
"cron": MustParseCid("bafk2bzaceaganmlpozvy4jywigs46pfrtdmhjjey6uyhpurplqbasojsislba"),
"datacap": MustParseCid("bafk2bzacebafqqe3wv5ytkfwmqzbmchgem66pw6yq6rl7w6vlhqsbkxnisswq"),
"eam": MustParseCid("bafk2bzaceawl3twv7iontkiiwgezkub2vvgd7cprhv7wvgpqjpeh4o6ygshlg"),
"ethaccount": MustParseCid("bafk2bzaceburkmtd63nmzxpux5rcxsbqr6x5didl2ce7al32g4tqrvo4pjz2i"),
"evm": MustParseCid("bafk2bzacea7tp4lop7ivhay3ozitkmxxurk74v4zse42ant47rh2uw5z3tq5e"),
"init": MustParseCid("bafk2bzaced23r54kwuebl7t6mdantbby5qpfduxwxfryeliof2enyqzhokix6"),
"multisig": MustParseCid("bafk2bzacebcn3rib6j6jvclys7dkf62hco45ssgamczkrtzt6xyewd6gt3mtu"),
"paymentchannel": MustParseCid("bafk2bzacecvas4leo44pqdguj22nnwqoqdgwajzrpm5d6ltkehc37ni6p6doq"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebiizh4ohvv6p4uxjusoygex4wxcgvudqmdl2fsh6ft6s2zt4tz6q"),
"storagemarket": MustParseCid("bafk2bzacedhkidshm7w2sqlw7izvaieyhkvmyhfsem6t6qfnkh7dnwqe56po2"),
"storageminer": MustParseCid("bafk2bzacedcmsibwfwhkp3sabmbyjmhqibyhjf3wwst7u5bkb2k6xpun3xevg"),
"storagepower": MustParseCid("bafk2bzacecrgnpypxnxzgglhlitaallfee3dl4ejy3y63knl7llnwba4ycf7i"),
"system": MustParseCid("bafk2bzacecl7gizbe52xj6sfm5glubkhrdblmzuwlid6lxrwr5zhcmv4dl2ew"),
"verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"),
},
}, {
Network: "devnet",
@ -212,23 +233,90 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, {
Network: "devnet",
Version: 10,
ManifestCid: MustParseCid("bafy2bzacea73thrlpfejrswlcu5uhe7rcgdewvmrcwoef6jzngsba3i4v5ibi"),
ManifestCid: MustParseCid("bafy2bzacedfwwsn5weycwkqrnusc37m6ut2uf42z5qvbukl67wi76mqtgafw2"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceau2o55aripm7kqrbzzog72zcduv5psnxzpohx5rdkykepc4z7aag"),
"cron": MustParseCid("bafk2bzacec5qc5xluwikf4lolfa4oe356iwep25tiezbxfdyg5jib54rhlh6q"),
"datacap": MustParseCid("bafk2bzacebo47u6q3xou5exsecjpa4rpfqjfm7vyhz4qlr3nk7p46trsk4occ"),
"eam": MustParseCid("bafk2bzacea6yeptevserd7ayf4ahokor4sdpizpxpbqwkuvvhzdkon672shsm"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzacebi46zgjili4luu3nqy6mno5k4skvo4cvs7genhkdfaukhtw7xirw"),
"init": MustParseCid("bafk2bzacedvf2bij6jovem2dfzkz347yvmydxj7vlgaiagosz5t3c5jyy43zu"),
"multisig": MustParseCid("bafk2bzacecukolwx6y5pcajnxg2aawiubgxo5zyj24a23zg5t4qu3k4qbofh4"),
"paymentchannel": MustParseCid("bafk2bzacecwyih7nodrwsw5vyl5zk7fapklje76jpowqjr6x6br2bm55smqqy"),
"reward": MustParseCid("bafk2bzacea6vfrcprxg2i4l5qnigf4c6pyvnjxpzfqr4pmph3elif7sfidrei"),
"storagemarket": MustParseCid("bafk2bzaceahradb3od4ahs46x6yriwvm36iabgtohhoiolubsumto5eravzbu"),
"storageminer": MustParseCid("bafk2bzacedekivqgvqapbepvzn6jte3xyymyg5yjuwy42xvboa6rcqnzgo74u"),
"storagepower": MustParseCid("bafk2bzacedkmiosllqqqarmr53twspyswdvsm7givwczgo3qqsxzpad4hzjma"),
"system": MustParseCid("bafk2bzaceagdymtxb4lxqqjgmnphbgdtdgveuuqaouswpzagj4bpbon3ptop4"),
"verifiedregistry": MustParseCid("bafk2bzacec556wsqldm22k2abshvvnsrawlm3bbqkwzht6ubcj76m2jsy3azi"),
"account": MustParseCid("bafk2bzacebb5txxkfexeaxa2th3rckxsxchzyss3ijgqbicf265h7rre2rvhm"),
"cron": MustParseCid("bafk2bzacecotn4gwluhamoqwnzgbg7ogehv26o5xnhjzltnzfv6utrlyanzek"),
"datacap": MustParseCid("bafk2bzacea4hket2srrtbewkf3tip6ellwpxdfbrzt5u47y57i2k6iojqqgba"),
"eam": MustParseCid("bafk2bzacecrg5sjpnmk3nu3vqyegkmjnvsjoumptseuu7zabeggu745bd2kwo"),
"ethaccount": MustParseCid("bafk2bzacedh4y3zvtgft3i6ift4rpptgr2dx67pvenowvq7yaspuf25gqgcdc"),
"evm": MustParseCid("bafk2bzacecrjgqoozymyoplrmtpi7bmkmggiqgpbgwkzooy2a67fjivuedm6a"),
"init": MustParseCid("bafk2bzacedof2ckc6w2qboxzxv4w67njcug4ut4cq3nnlrfybzsvlgnp4kt24"),
"multisig": MustParseCid("bafk2bzacec4eqajjqhl53tnkbs7glu7njlbtlditi7lxhvw33ezmxk6jae46y"),
"paymentchannel": MustParseCid("bafk2bzacec6nvdprqja7dy3qp5islebbbh2ifiyg2p7arbe6pocjhfe6xwkfy"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacecqaoqksjotl4wwsqt2wf6kqv6s372afi3r5on4bqj3u3a44px2rm"),
"storagemarket": MustParseCid("bafk2bzaceb7yefqlzyoxkgoug5k4kizy63izrg5udartw5l4d6j53xjwdxbg4"),
"storageminer": MustParseCid("bafk2bzaceagmuxcgdj65yuvtfrcup5viwkhhhlzslpdd4j6v6qxmhxtcssc6u"),
"storagepower": MustParseCid("bafk2bzacedt2qu6ykj3bjsfhchg2gxvc6asfb7c4tmranl76n4ojut5d6sgqm"),
"system": MustParseCid("bafk2bzacebp4ysxqv4cy633pgdxjlbwkwqkokc2fgez77y73abpt5hkthczn6"),
"verifiedregistry": MustParseCid("bafk2bzaceb7odugx7meltvt2gra4vogn2g6avbgysivvdccldylusjcfsnfhy"),
},
}, {
Network: "hyperspace",
Version: 8,
ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"),
"cron": MustParseCid("bafk2bzaceahgq64awp4f7li3hdgimc4upqvdvltpmeywckvens33umcxt424a"),
"datacap": MustParseCid("bafk2bzacebkxn52ttooaslkwncijk3bgd3tm2zw7vijdhwvg2cxnxbrzmmq5e"),
"eam": MustParseCid("bafk2bzaceczhgub5anrnaf7ol65mu54gsgwcj6c6m3yhet7rhxm2l6kz4s4ru"),
"ethaccount": MustParseCid("bafk2bzacealn5enbxyxbfs7gbsjbyma2zk3bcr7okvflxhpr753d4eh6ixooa"),
"evm": MustParseCid("bafk2bzacedljkrmazyewawpnddrkzrt55556374dw2pm2hokgkompgzw4vx5y"),
"init": MustParseCid("bafk2bzacec55gyyaqjrw7zughywocgwcjvv6k5fijjpjw4xgckuqz6pjtff5a"),
"multisig": MustParseCid("bafk2bzaceblozbdzybdivvjdiid4jwm2jc6x5a66sunh2vvwsqba6wzqmr7i6"),
"paymentchannel": MustParseCid("bafk2bzacealcyke5a6n24efs6qe4iikynpk2twqssyugy7jcyf6p6shgw2iwa"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebafzaqhwsm3nmsfwcd6ngvx6ev6zlcpyfljqh4kb77vok6opban6"),
"storagemarket": MustParseCid("bafk2bzacecrjfg4p7fxznsdkoobs4po2ve3ywixrirrk6netgxh63qqaefamg"),
"storageminer": MustParseCid("bafk2bzaceb3ctd4atxwhdkmlg4i63zxo5aopknlj7l5kaiqr22xpcmico6vg4"),
"storagepower": MustParseCid("bafk2bzacecvcix3ugopvby2vah5wwiu5cqjedwzwkanmr34kdoc4f3o6p7nsq"),
"system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"),
"verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"),
},
}, {
Network: "hyperspace",
Version: 9,
ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"),
"cron": MustParseCid("bafk2bzaceahgq64awp4f7li3hdgimc4upqvdvltpmeywckvens33umcxt424a"),
"datacap": MustParseCid("bafk2bzacebkxn52ttooaslkwncijk3bgd3tm2zw7vijdhwvg2cxnxbrzmmq5e"),
"eam": MustParseCid("bafk2bzaceczhgub5anrnaf7ol65mu54gsgwcj6c6m3yhet7rhxm2l6kz4s4ru"),
"ethaccount": MustParseCid("bafk2bzacealn5enbxyxbfs7gbsjbyma2zk3bcr7okvflxhpr753d4eh6ixooa"),
"evm": MustParseCid("bafk2bzacedljkrmazyewawpnddrkzrt55556374dw2pm2hokgkompgzw4vx5y"),
"init": MustParseCid("bafk2bzacec55gyyaqjrw7zughywocgwcjvv6k5fijjpjw4xgckuqz6pjtff5a"),
"multisig": MustParseCid("bafk2bzaceblozbdzybdivvjdiid4jwm2jc6x5a66sunh2vvwsqba6wzqmr7i6"),
"paymentchannel": MustParseCid("bafk2bzacealcyke5a6n24efs6qe4iikynpk2twqssyugy7jcyf6p6shgw2iwa"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebafzaqhwsm3nmsfwcd6ngvx6ev6zlcpyfljqh4kb77vok6opban6"),
"storagemarket": MustParseCid("bafk2bzacecrjfg4p7fxznsdkoobs4po2ve3ywixrirrk6netgxh63qqaefamg"),
"storageminer": MustParseCid("bafk2bzaceb3ctd4atxwhdkmlg4i63zxo5aopknlj7l5kaiqr22xpcmico6vg4"),
"storagepower": MustParseCid("bafk2bzacecvcix3ugopvby2vah5wwiu5cqjedwzwkanmr34kdoc4f3o6p7nsq"),
"system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"),
"verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"),
},
}, {
Network: "hyperspace",
Version: 10,
ManifestCid: MustParseCid("bafy2bzacedimb4dzty5tsyy3ucbcxai7crli452wn5cguhpmuelq74i4bffoo"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"),
"cron": MustParseCid("bafk2bzaceahgq64awp4f7li3hdgimc4upqvdvltpmeywckvens33umcxt424a"),
"datacap": MustParseCid("bafk2bzacebkxn52ttooaslkwncijk3bgd3tm2zw7vijdhwvg2cxnxbrzmmq5e"),
"eam": MustParseCid("bafk2bzacedg5bnw3ic2ub4mb2agrvdowpqd7xyjv6v2ndlkugnrtjgzzfxqlw"),
"ethaccount": MustParseCid("bafk2bzacealn5enbxyxbfs7gbsjbyma2zk3bcr7okvflxhpr753d4eh6ixooa"),
"evm": MustParseCid("bafk2bzacedljkrmazyewawpnddrkzrt55556374dw2pm2hokgkompgzw4vx5y"),
"init": MustParseCid("bafk2bzacec55gyyaqjrw7zughywocgwcjvv6k5fijjpjw4xgckuqz6pjtff5a"),
"multisig": MustParseCid("bafk2bzaceblozbdzybdivvjdiid4jwm2jc6x5a66sunh2vvwsqba6wzqmr7i6"),
"paymentchannel": MustParseCid("bafk2bzacealcyke5a6n24efs6qe4iikynpk2twqssyugy7jcyf6p6shgw2iwa"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebafzaqhwsm3nmsfwcd6ngvx6ev6zlcpyfljqh4kb77vok6opban6"),
"storagemarket": MustParseCid("bafk2bzacecrjfg4p7fxznsdkoobs4po2ve3ywixrirrk6netgxh63qqaefamg"),
"storageminer": MustParseCid("bafk2bzaceb3ctd4atxwhdkmlg4i63zxo5aopknlj7l5kaiqr22xpcmico6vg4"),
"storagepower": MustParseCid("bafk2bzacecvcix3ugopvby2vah5wwiu5cqjedwzwkanmr34kdoc4f3o6p7nsq"),
"system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"),
"verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"),
},
}, {
Network: "mainnet",
@ -268,23 +356,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, {
Network: "mainnet",
Version: 10,
ManifestCid: MustParseCid("bafy2bzaceduyggnyqhlr346hfw32tbobzrvhzhill33zhe7jw64pmwjci2xoc"),
ManifestCid: MustParseCid("bafy2bzaceat4ut5xv3qn4lvvkvwvdn6gtlbnqzvueh67fjqlemw6eled5oqnc"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacedmr3wxl7qmhquageorrt3aavbzqfpm7eymxidakwuhaobu7dseqs"),
"cron": MustParseCid("bafk2bzaceblekxapm5nnqnxmw3mk27236iyutvbhhpsc3fyde7zi7guccn7cc"),
"datacap": MustParseCid("bafk2bzacedu4jevyvqsilq7bq4uhegbkm75muwebc5ifqpfaojwhexf2j4i6a"),
"eam": MustParseCid("bafk2bzacedc7224twbolvdq6iwc7ybdpah2ywe3ueo33jv67ecimndinle374"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzaceaggldo6wmkvp5innv4pnjv4xnpedspzofvma3dhu7vk45hh5djoq"),
"init": MustParseCid("bafk2bzacedutlaebaczkdi4vqvt3xim24u3whleqk2r4lufjd5jnmxcosea6q"),
"multisig": MustParseCid("bafk2bzaceatiqxjwtugpzus3s52zoggnrftxqn7kiw3obvjgkjvtd6zr3636q"),
"paymentchannel": MustParseCid("bafk2bzacebyviac6i43gtsvmjfg6mzcp6rwgz44axidc7m432btbmvt7i2m2g"),
"reward": MustParseCid("bafk2bzacecbcnlvk2izojpfoaksitqenhzaofn6ynxx5pegl4y45wjlouexdi"),
"storagemarket": MustParseCid("bafk2bzacebobteeoz2jycplgtydfyltzughegz2sopn6pzy2udjfvuo77joyk"),
"storageminer": MustParseCid("bafk2bzacecwcypas3y6u4rya7qolfwmou437xgrjxh7mnnim7bo3nhk4dscxw"),
"storagepower": MustParseCid("bafk2bzacec62kids6rcrdmdeqhwiz3s5rs35s5gn25ilwemgmm6jqnr2rnaaq"),
"system": MustParseCid("bafk2bzacecj3c4bjbs2xfttn7zqle7yocqh47u2s7hwuxrsn7fi5h74tcyxoc"),
"verifiedregistry": MustParseCid("bafk2bzacedgf7zbnlste5ukzueduemkimiit64scz7lvebztufx5jxtx6gkz2"),
"account": MustParseCid("bafk2bzacedsn6i2flkpk6sb4iuejo7gfl5n6fhsdawggtbsihlrrjtvs7oepu"),
"cron": MustParseCid("bafk2bzacecw4guere7ba2canyi2622lw52b5qbn7iubckcp5cwlmx2kw7qqwy"),
"datacap": MustParseCid("bafk2bzaceat2ncckd2jjjqcovd3ib4sylwff7jk7rlk6gr5d2gmrrc7isrmu2"),
"eam": MustParseCid("bafk2bzacebl7267zqf7aubpl7n6ligulayhz65dpgn3ii26b3wwjwytlsdc3i"),
"ethaccount": MustParseCid("bafk2bzacedmwzkbytxfn7exmxxosomvix4mpyxrmupeqw45aofqmdq5q7mgqe"),
"evm": MustParseCid("bafk2bzacecrrwixyqwphxaybhy5zxuawkhncq5tgtuz2ind4bl22oivzjidoq"),
"init": MustParseCid("bafk2bzacec6276d7ls3hhuqibqorn3yp45mv7hroczf3bgb6jkhmbb2zqt3bw"),
"multisig": MustParseCid("bafk2bzaceahggxrnjj3w3cgtko54srssqyhcs4x6y55ytego6jf2owg5piw3y"),
"paymentchannel": MustParseCid("bafk2bzaceaobaqjamso57bkjv3n4ilv7lfropgrncnnej666w3tegmr4cfgve"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacecqet4s7abe4owznq2wtdefe2z2w5isbde2gj7u3hwgf54di4r7hy"),
"storagemarket": MustParseCid("bafk2bzacebgk2q2ktrqauzop6ha4pcq5gpf6g24hprxnp6wdmlzf724e5sx7i"),
"storageminer": MustParseCid("bafk2bzacecqrm4tlmzci7vilmcchr4lq2e6yyrlhy6ofbuecjna2phmbq4h2a"),
"storagepower": MustParseCid("bafk2bzaceco674a5e5lpv5leui65bljxzgyc2ypdquaow55iuckmq5rvsghr6"),
"system": MustParseCid("bafk2bzacedlt3zcsbw2vucbydptbcfudw5y5pkhhxe26m7pjod6rkxkuzn52w"),
"verifiedregistry": MustParseCid("bafk2bzacea2eehyf7h3m6ydh46piu2gtr4fawpqzh3brtmybgi2tyxf5nwj6m"),
},
}, {
Network: "testing",
@ -324,23 +413,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, {
Network: "testing",
Version: 10,
ManifestCid: MustParseCid("bafy2bzacearlgbespxi2zdrybtp2rrbwscmtbyou5qa2egbdvcz6v2yjjqvjo"),
ManifestCid: MustParseCid("bafy2bzacearh2dy6uzcfvruckai5qbf7banklkg6uezaa7w6onsmdfxn2qxbs"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceba6me5ipkcijuhyypnzjydhv3ebi2ctailar7mtzlk4vk3rbxfee"),
"cron": MustParseCid("bafk2bzacea6k2mai2xnakygqvbigivfrvv5q7d34qrzjv2crkqtwbjxnxmkbe"),
"datacap": MustParseCid("bafk2bzaceah4oxcgck6bcfkzctm2klpvmltyidq7uxnlkcap6ypi3lnkcvrqk"),
"eam": MustParseCid("bafk2bzacedjtkvocrnkrot2oztsfrxtpwl32wwbmbkrjfbbm4xipwzrhhxn5c"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzaced6vhabkr2ojpjzsybrq5yvksjzpjk6yei6fwobkwwydlj5f473pw"),
"init": MustParseCid("bafk2bzaceaib3o5e7wop7kwjirgpferqarmngrgjkur2yhdnwplctidpxsgme"),
"multisig": MustParseCid("bafk2bzaced4z3awacxumq6yr33a3adu2legb7colahgvqpmigs3fvvjxs3byc"),
"paymentchannel": MustParseCid("bafk2bzaceb6mfi24mpzt7qlkratj2tdtqo7aia67zcztuslrxcjaycz6fnai6"),
"reward": MustParseCid("bafk2bzacebngh5kwtem4ncarpjtxhs4rwyoficttkgxlsjtiz5ucdi4p3czoc"),
"storagemarket": MustParseCid("bafk2bzacecnsibyil62jfq2gbkoe6c2epehfcrxzjmqjnwz7kxab2hkbu3lks"),
"storageminer": MustParseCid("bafk2bzacedzw4vkrt3sdkhagpvn62pknyyjkcrzewncvtvae5qgwe6ulzx4a4"),
"storagepower": MustParseCid("bafk2bzacedxgadibot6nzvripqt3z5shvjsoscupinejnsvswq4cbeskblwyy"),
"system": MustParseCid("bafk2bzacedm24avrmp5o5odhpad43qeglooflygwh4ah7qnzbij2h4c3v6cge"),
"verifiedregistry": MustParseCid("bafk2bzaceapq3j6ww3ofytwq3pz3obumaqsyg3wrm6tksdh7op23a72co3rya"),
"account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"),
"cron": MustParseCid("bafk2bzacebxp4whb4ocqxnbvqlz3kckarabtyvhjbhqvrdwhejuffwactyiss"),
"datacap": MustParseCid("bafk2bzacedepm3zas6vqryruwiz7d3axkneo7v66q65gf2dlpfd53pjlycrg4"),
"eam": MustParseCid("bafk2bzacedl4q6l3m5uvunuviwlxicyweszrahipxfpf3nt6wspvcdi4ryzyk"),
"ethaccount": MustParseCid("bafk2bzacecbhz4ipg773lsovgpjysm6fxl2i7y2wuxadqnt4s4vm3nd2qodb4"),
"evm": MustParseCid("bafk2bzaced5efc2bi7ulqsep4ej74hxwbjap2qi7lojiqzfsowxr4kylkwzk6"),
"init": MustParseCid("bafk2bzacebqym5i5eciyyyzsimu73z6bkffpm5hzjpx3gwcm64pm2fh7okrja"),
"multisig": MustParseCid("bafk2bzacecmlyngek7qvj5ezaaitadrycapup3mbty4ijlzun6g23tcoysxle"),
"paymentchannel": MustParseCid("bafk2bzacedspin4hxpgnxkjen3hsxpcc52oc5q4ypukl4qq6vaytcgmmi7hl4"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacecmumnnqkqnoa23hhsfgwccwvmksr2q65tznbves6x2a6fhwvtm7a"),
"storagemarket": MustParseCid("bafk2bzacea2re4nxba7mtlrwdxabu2i3l2fwbuw2veb4p7qbvrsaocgablqvi"),
"storageminer": MustParseCid("bafk2bzacecixm7d7d5ltsp6mubzw5s3fv335cjuwwy7oqovujn3xlyk6twivs"),
"storagepower": MustParseCid("bafk2bzaced5lqpftacjsflcgfwlm32gzckpi3ndj3kd3prtqqi2lfj3uhl2je"),
"system": MustParseCid("bafk2bzaceaafqf7lwaiqx5po6b3l4dfg4xsr5qhfk3bjgoi7qke2mfy3shla4"),
"verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"),
},
}, {
Network: "testing-fake-proofs",
@ -380,22 +470,23 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, {
Network: "testing-fake-proofs",
Version: 10,
ManifestCid: MustParseCid("bafy2bzacea4irr2oxhclwt4mvtrevbzb7mbqddcebjz7bkqjq6eoflpfhencc"),
ManifestCid: MustParseCid("bafy2bzacedw6kk3u2vjexzqmm3vtvusd42lllk7wbnsrlxxmt35smsnmiatca"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceba6me5ipkcijuhyypnzjydhv3ebi2ctailar7mtzlk4vk3rbxfee"),
"cron": MustParseCid("bafk2bzacea6k2mai2xnakygqvbigivfrvv5q7d34qrzjv2crkqtwbjxnxmkbe"),
"datacap": MustParseCid("bafk2bzaceah4oxcgck6bcfkzctm2klpvmltyidq7uxnlkcap6ypi3lnkcvrqk"),
"eam": MustParseCid("bafk2bzacedjtkvocrnkrot2oztsfrxtpwl32wwbmbkrjfbbm4xipwzrhhxn5c"),
"embryo": MustParseCid("bafk2bzacebj2mj5zlcs3yjlgpbznzistfjkdlwaoncjziliqrxqavvz4dcvnk"),
"evm": MustParseCid("bafk2bzaced6vhabkr2ojpjzsybrq5yvksjzpjk6yei6fwobkwwydlj5f473pw"),
"init": MustParseCid("bafk2bzaceaib3o5e7wop7kwjirgpferqarmngrgjkur2yhdnwplctidpxsgme"),
"multisig": MustParseCid("bafk2bzaced4z3awacxumq6yr33a3adu2legb7colahgvqpmigs3fvvjxs3byc"),
"paymentchannel": MustParseCid("bafk2bzaceb6mfi24mpzt7qlkratj2tdtqo7aia67zcztuslrxcjaycz6fnai6"),
"reward": MustParseCid("bafk2bzacebngh5kwtem4ncarpjtxhs4rwyoficttkgxlsjtiz5ucdi4p3czoc"),
"storagemarket": MustParseCid("bafk2bzacecnsibyil62jfq2gbkoe6c2epehfcrxzjmqjnwz7kxab2hkbu3lks"),
"storageminer": MustParseCid("bafk2bzaceb4grddnw54gczgcdak5a2gqvwed66mhibbug6qu4jy35bf45jltg"),
"storagepower": MustParseCid("bafk2bzacedp2dnbk4bg3hhaeztre4q3jv7eqs267rlafszpggb2njjn3x5eru"),
"system": MustParseCid("bafk2bzacedm24avrmp5o5odhpad43qeglooflygwh4ah7qnzbij2h4c3v6cge"),
"verifiedregistry": MustParseCid("bafk2bzaceapq3j6ww3ofytwq3pz3obumaqsyg3wrm6tksdh7op23a72co3rya"),
"account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"),
"cron": MustParseCid("bafk2bzacebxp4whb4ocqxnbvqlz3kckarabtyvhjbhqvrdwhejuffwactyiss"),
"datacap": MustParseCid("bafk2bzacedepm3zas6vqryruwiz7d3axkneo7v66q65gf2dlpfd53pjlycrg4"),
"eam": MustParseCid("bafk2bzacedl4q6l3m5uvunuviwlxicyweszrahipxfpf3nt6wspvcdi4ryzyk"),
"ethaccount": MustParseCid("bafk2bzacecbhz4ipg773lsovgpjysm6fxl2i7y2wuxadqnt4s4vm3nd2qodb4"),
"evm": MustParseCid("bafk2bzaced5efc2bi7ulqsep4ej74hxwbjap2qi7lojiqzfsowxr4kylkwzk6"),
"init": MustParseCid("bafk2bzacebqym5i5eciyyyzsimu73z6bkffpm5hzjpx3gwcm64pm2fh7okrja"),
"multisig": MustParseCid("bafk2bzacecmlyngek7qvj5ezaaitadrycapup3mbty4ijlzun6g23tcoysxle"),
"paymentchannel": MustParseCid("bafk2bzacedspin4hxpgnxkjen3hsxpcc52oc5q4ypukl4qq6vaytcgmmi7hl4"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacecmumnnqkqnoa23hhsfgwccwvmksr2q65tznbves6x2a6fhwvtm7a"),
"storagemarket": MustParseCid("bafk2bzacea2re4nxba7mtlrwdxabu2i3l2fwbuw2veb4p7qbvrsaocgablqvi"),
"storageminer": MustParseCid("bafk2bzacedz4mmupganqbwe6mz4636zepooh5ipxb36tybsrf6ynewrfdihl6"),
"storagepower": MustParseCid("bafk2bzacedcqv6k2fszpfb7zpw6q6c6fe2u7g2zefabcntp46xgv3owosgymy"),
"system": MustParseCid("bafk2bzaceaafqf7lwaiqx5po6b3l4dfg4xsr5qhfk3bjgoi7qke2mfy3shla4"),
"verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"),
},
}}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -21,6 +21,7 @@ const GenesisFile = ""
var NetworkBundle = "devnet"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = true
const GenesisNetworkVersion = network.Version18
@ -58,6 +59,8 @@ var UpgradeSkyrHeight = abi.ChainEpoch(-19)
var UpgradeSharkHeight = abi.ChainEpoch(-20)
var UpgradeHyggeHeight = abi.ChainEpoch(-21)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
}
@ -110,6 +113,7 @@ func init() {
UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight)
UpgradeSkyrHeight = getUpgradeHeight("LOTUS_SKYR_HEIGHT", UpgradeSkyrHeight)
UpgradeSharkHeight = getUpgradeHeight("LOTUS_SHARK_HEIGHT", UpgradeSharkHeight)
UpgradeHyggeHeight = getUpgradeHeight("LOTUS_HYGGE_HEIGHT", UpgradeHyggeHeight)
BuildType |= Build2k
@ -130,4 +134,8 @@ const InteractivePoRepConfidence = 6
const BootstrapPeerThreshold = 1
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 31415926
var WhitelistedBlock = cid.Undef

View File

@ -23,6 +23,7 @@ const GenesisNetworkVersion = network.Version16
var NetworkBundle = "butterflynet"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = false
const BootstrappersFile = "butterflynet.pi"
const GenesisFile = "butterflynet.car"
@ -49,7 +50,8 @@ const UpgradeHyperdriveHeight = -16
const UpgradeChocolateHeight = -17
const UpgradeOhSnapHeight = -18
const UpgradeSkyrHeight = -19
const UpgradeSharkHeight = abi.ChainEpoch(600)
const UpgradeSharkHeight = abi.ChainEpoch(-20)
const UpgradeHyggeHeight = abi.ChainEpoch(600)
var SupportedProofTypes = []abi.RegisteredSealProof{
abi.RegisteredSealProof_StackedDrg512MiBV1,
@ -80,4 +82,8 @@ const PropagationDelaySecs = uint64(6)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 2
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 3141592
var WhitelistedBlock = cid.Undef

View File

@ -4,6 +4,7 @@
package build
import (
"math"
"os"
"strconv"
@ -26,6 +27,7 @@ const GenesisNetworkVersion = network.Version0
var NetworkBundle = "calibrationnet"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = false
const BootstrappersFile = "calibnet.pi"
const GenesisFile = "calibnet.car"
@ -69,6 +71,8 @@ const UpgradeSkyrHeight = 510
const UpgradeSharkHeight = 16800 // 6 days after genesis
const UpgradeHyggeHeight = math.MaxInt64
var SupportedProofTypes = []abi.RegisteredSealProof{
abi.RegisteredSealProof_StackedDrg32GiBV1,
abi.RegisteredSealProof_StackedDrg64GiBV1,
@ -113,4 +117,8 @@ var PropagationDelaySecs = uint64(10)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 4
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 314159
var WhitelistedBlock = cid.Undef

View File

@ -0,0 +1,94 @@
//go:build hyperspacenet
// +build hyperspacenet
package build
import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/network"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
)
var NetworkBundle = "hyperspace"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = false
const BootstrappersFile = "hyperspacenet.pi"
const GenesisFile = "hyperspacenet.car"
const GenesisNetworkVersion = network.Version18
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
const BreezeGasTampingDuration = 120
var UpgradeSmokeHeight = abi.ChainEpoch(-1)
var UpgradeIgnitionHeight = abi.ChainEpoch(-2)
var UpgradeRefuelHeight = abi.ChainEpoch(-3)
var UpgradeTapeHeight = abi.ChainEpoch(-4)
var UpgradeAssemblyHeight = abi.ChainEpoch(-5)
var UpgradeLiftoffHeight = abi.ChainEpoch(-6)
var UpgradeKumquatHeight = abi.ChainEpoch(-7)
var UpgradeCalicoHeight = abi.ChainEpoch(-9)
var UpgradePersianHeight = abi.ChainEpoch(-10)
var UpgradeOrangeHeight = abi.ChainEpoch(-11)
var UpgradeClausHeight = abi.ChainEpoch(-12)
var UpgradeTrustHeight = abi.ChainEpoch(-13)
var UpgradeNorwegianHeight = abi.ChainEpoch(-14)
var UpgradeTurboHeight = abi.ChainEpoch(-15)
var UpgradeHyperdriveHeight = abi.ChainEpoch(-16)
var UpgradeChocolateHeight = abi.ChainEpoch(-17)
var UpgradeOhSnapHeight = abi.ChainEpoch(-18)
var UpgradeSkyrHeight = abi.ChainEpoch(-19)
var UpgradeSharkHeight = abi.ChainEpoch(-20)
var UpgradeHyggeHeight = abi.ChainEpoch(-21)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
}
var SupportedProofTypes = []abi.RegisteredSealProof{
abi.RegisteredSealProof_StackedDrg512MiBV1,
abi.RegisteredSealProof_StackedDrg32GiBV1,
abi.RegisteredSealProof_StackedDrg64GiBV1,
}
var ConsensusMinerMinPower = abi.NewStoragePower(16 << 30)
var MinVerifiedDealSize = abi.NewStoragePower(1 << 20)
var PreCommitChallengeDelay = abi.ChainEpoch(10)
func init() {
policy.SetSupportedProofTypes(SupportedProofTypes...)
policy.SetConsensusMinerMinPower(ConsensusMinerMinPower)
policy.SetMinVerifiedDealSize(MinVerifiedDealSize)
policy.SetPreCommitChallengeDelay(PreCommitChallengeDelay)
BuildType = BuildHyperspacenet
SetAddressNetwork(address.Testnet)
Devnet = true
}
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
const PropagationDelaySecs = uint64(6)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 2
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 3141
var WhitelistedBlock = cid.Undef

View File

@ -20,6 +20,7 @@ import (
var NetworkBundle = "caterpillarnet"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = false
const BootstrappersFile = "interopnet.pi"
const GenesisFile = "interopnet.car"
@ -49,7 +50,9 @@ var UpgradeChocolateHeight = abi.ChainEpoch(-17)
var UpgradeOhSnapHeight = abi.ChainEpoch(-18)
var UpgradeSkyrHeight = abi.ChainEpoch(-19)
const UpgradeSharkHeight = abi.ChainEpoch(99999999999999)
const UpgradeSharkHeight = abi.ChainEpoch(-20)
const UpgradeHyggeHeight = abi.ChainEpoch(99999999999999)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
@ -104,6 +107,7 @@ func init() {
UpgradeOhSnapHeight = getUpgradeHeight("LOTUS_OHSNAP_HEIGHT", UpgradeOhSnapHeight)
UpgradeSkyrHeight = getUpgradeHeight("LOTUS_SKYR_HEIGHT", UpgradeSkyrHeight)
UpgradeSharkHeight = getUpgradeHeight("LOTUS_SHARK_HEIGHT", UpgradeSharkHeight)
UpgradeHyggeHeight = getUpgradeHeight("LOTUS_HYGGE_HEIGHT", UpgradeHyggeHeight)
BuildType |= BuildInteropnet
SetAddressNetwork(address.Testnet)
@ -118,4 +122,9 @@ const PropagationDelaySecs = uint64(6)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 2
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
// TODO same as butterfly for now, as we didn't submit an assignment for interopnet.
const Eip155ChainId = 3141592
var WhitelistedBlock = cid.Undef

View File

@ -1,5 +1,5 @@
//go:build !debug && !2k && !testground && !calibnet && !butterflynet && !interopnet
// +build !debug,!2k,!testground,!calibnet,!butterflynet,!interopnet
//go:build !debug && !2k && !testground && !calibnet && !butterflynet && !interopnet && !wallabynet && !hyperspacenet
// +build !debug,!2k,!testground,!calibnet,!butterflynet,!interopnet,!wallabynet,!hyperspacenet
package build
@ -25,6 +25,9 @@ var NetworkBundle = "mainnet"
// NOTE: DO NOT change this unless you REALLY know what you're doing. This is consensus critical.
var BundleOverrides map[actorstypes.Version]string
// NOTE: DO NOT change this unless you REALLY know what you're doing. This is consensus critical.
const ActorDebugging = false
const GenesisNetworkVersion = network.Version0
const BootstrappersFile = "mainnet.pi"
@ -56,6 +59,7 @@ const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
const UpgradeOrangeHeight = 336458
// 2020-12-22T02:00:00Z
// var because of wdpost_test.go
var UpgradeClausHeight = abi.ChainEpoch(343200)
// 2021-03-04T00:00:30Z
@ -80,7 +84,10 @@ const UpgradeOhSnapHeight = 1594680
const UpgradeSkyrHeight = 1960320
// 2022-11-30T14:00:00Z
var UpgradeSharkHeight = abi.ChainEpoch(2383680)
const UpgradeSharkHeight = 2383680
// ??????????????
var UpgradeHyggeHeight = abi.ChainEpoch(math.MaxInt64)
var SupportedProofTypes = []abi.RegisteredSealProof{
abi.RegisteredSealProof_StackedDrg32GiBV1,
@ -95,8 +102,8 @@ func init() {
SetAddressNetwork(address.Mainnet)
}
if os.Getenv("LOTUS_DISABLE_SHARK") == "1" {
UpgradeSharkHeight = math.MaxInt64
if os.Getenv("LOTUS_DISABLE_HYGGE") == "1" {
UpgradeHyggeHeight = math.MaxInt64
}
// NOTE: DO NOT change this unless you REALLY know what you're doing. This is not consensus critical, however,
@ -124,5 +131,9 @@ const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 4
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 314
// we skip checks on message validity in this block to sidestep the zero-bls signature
var WhitelistedBlock = MustParseCid("bafy2bzaceapyg2uyzk7vueh3xccxkuwbz3nxewjyguoxvhx77malc2lzn2ybi")

View File

@ -108,6 +108,7 @@ var (
UpgradeOhSnapHeight abi.ChainEpoch = -17
UpgradeSkyrHeight abi.ChainEpoch = -18
UpgradeSharkHeight abi.ChainEpoch = -19
UpgradeHyggeHeight abi.ChainEpoch = -20
DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
@ -116,6 +117,7 @@ var (
GenesisNetworkVersion = network.Version0
NetworkBundle = "devnet"
BundleOverrides map[actorstypes.Version]string
ActorDebugging = true
NewestNetworkVersion = network.Version16
ActorUpgradeNetworkVersion = network.Version16
@ -129,3 +131,7 @@ var (
)
const BootstrapPeerThreshold = 1
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 31415926

94
build/params_wallaby.go Normal file
View File

@ -0,0 +1,94 @@
//go:build wallabynet
// +build wallabynet
package build
import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/network"
builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin"
"github.com/filecoin-project/lotus/chain/actors/policy"
)
var NetworkBundle = "wallaby"
var BundleOverrides map[actorstypes.Version]string
var ActorDebugging = false
const BootstrappersFile = "wallabynet.pi"
const GenesisFile = "wallabynet.car"
const GenesisNetworkVersion = network.Version18
var UpgradeBreezeHeight = abi.ChainEpoch(-1)
const BreezeGasTampingDuration = 120
var UpgradeSmokeHeight = abi.ChainEpoch(-1)
var UpgradeIgnitionHeight = abi.ChainEpoch(-2)
var UpgradeRefuelHeight = abi.ChainEpoch(-3)
var UpgradeTapeHeight = abi.ChainEpoch(-4)
var UpgradeAssemblyHeight = abi.ChainEpoch(-5)
var UpgradeLiftoffHeight = abi.ChainEpoch(-6)
var UpgradeKumquatHeight = abi.ChainEpoch(-7)
var UpgradeCalicoHeight = abi.ChainEpoch(-9)
var UpgradePersianHeight = abi.ChainEpoch(-10)
var UpgradeOrangeHeight = abi.ChainEpoch(-11)
var UpgradeClausHeight = abi.ChainEpoch(-12)
var UpgradeTrustHeight = abi.ChainEpoch(-13)
var UpgradeNorwegianHeight = abi.ChainEpoch(-14)
var UpgradeTurboHeight = abi.ChainEpoch(-15)
var UpgradeHyperdriveHeight = abi.ChainEpoch(-16)
var UpgradeChocolateHeight = abi.ChainEpoch(-17)
var UpgradeOhSnapHeight = abi.ChainEpoch(-18)
var UpgradeSkyrHeight = abi.ChainEpoch(-19)
var UpgradeSharkHeight = abi.ChainEpoch(-20)
var UpgradeHyggeHeight = abi.ChainEpoch(-21)
var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet,
}
var SupportedProofTypes = []abi.RegisteredSealProof{
abi.RegisteredSealProof_StackedDrg512MiBV1,
abi.RegisteredSealProof_StackedDrg32GiBV1,
abi.RegisteredSealProof_StackedDrg64GiBV1,
}
var ConsensusMinerMinPower = abi.NewStoragePower(16 << 30)
var MinVerifiedDealSize = abi.NewStoragePower(1 << 20)
var PreCommitChallengeDelay = abi.ChainEpoch(10)
func init() {
policy.SetSupportedProofTypes(SupportedProofTypes...)
policy.SetConsensusMinerMinPower(ConsensusMinerMinPower)
policy.SetMinVerifiedDealSize(MinVerifiedDealSize)
policy.SetPreCommitChallengeDelay(PreCommitChallengeDelay)
BuildType = BuildWallabynet
SetAddressNetwork(address.Testnet)
Devnet = true
}
const BlockDelaySecs = uint64(builtin2.EpochDurationSeconds)
const PropagationDelaySecs = uint64(6)
// BootstrapPeerThreshold is the minimum number peers we need to track for a sync worker to start
const BootstrapPeerThreshold = 2
// ChainId defines the chain ID used in the Ethereum JSON-RPC endpoint.
// As per https://github.com/ethereum-lists/chains
const Eip155ChainId = 31415
var WhitelistedBlock = cid.Undef

View File

@ -6,13 +6,15 @@ var CurrentCommit string
var BuildType int
const (
BuildDefault = 0
BuildMainnet = 0x1
Build2k = 0x2
BuildDebug = 0x3
BuildCalibnet = 0x4
BuildInteropnet = 0x5
BuildButterflynet = 0x7
BuildDefault = 0
BuildMainnet = 0x1
Build2k = 0x2
BuildDebug = 0x3
BuildCalibnet = 0x4
BuildInteropnet = 0x5
BuildButterflynet = 0x7
BuildWallabynet = 0x8
BuildHyperspacenet = 0x9
)
func BuildTypeString() string {
@ -31,6 +33,10 @@ func BuildTypeString() string {
return "+interopnet"
case BuildButterflynet:
return "+butterflynet"
case BuildWallabynet:
return "+wallabynet"
case BuildHyperspacenet:
return "+hyperspacenet"
default:
return "+huh?"
}

View File

@ -274,6 +274,33 @@ func IsPaymentChannelActor(c cid.Cid) bool {
return false
}
func IsPlaceholderActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.PlaceholderKey
}
return false
}
func IsEvmActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.EvmKey
}
return false
}
func IsEthAccountActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.EthAccountKey
}
return false
}
func makeAddress(addr string) address.Address {
ret, err := address.NewFromString(addr)
if err != nil {

View File

@ -153,6 +153,33 @@ func IsPaymentChannelActor(c cid.Cid) bool {
return false
}
func IsPlaceholderActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.PlaceholderKey
}
return false
}
func IsEvmActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.EvmKey
}
return false
}
func IsEthAccountActor(c cid.Cid) bool {
name, _, ok := actors.GetActorMetaByCode(c)
if ok {
return name == manifest.EthAccountKey
}
return false
}
func makeAddress(addr string) address.Address {
ret, err := address.NewFromString(addr)
if err != nil {

View File

@ -13,11 +13,15 @@ import (
account10 "github.com/filecoin-project/go-state-types/builtin/v10/account"
cron10 "github.com/filecoin-project/go-state-types/builtin/v10/cron"
datacap10 "github.com/filecoin-project/go-state-types/builtin/v10/datacap"
eam10 "github.com/filecoin-project/go-state-types/builtin/v10/eam"
ethaccount10 "github.com/filecoin-project/go-state-types/builtin/v10/ethaccount"
evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm"
_init10 "github.com/filecoin-project/go-state-types/builtin/v10/init"
market10 "github.com/filecoin-project/go-state-types/builtin/v10/market"
miner10 "github.com/filecoin-project/go-state-types/builtin/v10/miner"
multisig10 "github.com/filecoin-project/go-state-types/builtin/v10/multisig"
paych10 "github.com/filecoin-project/go-state-types/builtin/v10/paych"
placeholder10 "github.com/filecoin-project/go-state-types/builtin/v10/placeholder"
power10 "github.com/filecoin-project/go-state-types/builtin/v10/power"
reward10 "github.com/filecoin-project/go-state-types/builtin/v10/reward"
system10 "github.com/filecoin-project/go-state-types/builtin/v10/system"
@ -265,6 +269,7 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry {
methods: datacap9.Methods,
state: new(datacap9.State),
})
}
}
@ -343,6 +348,32 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry {
methods: datacap10.Methods,
state: new(datacap10.State),
})
case manifest.EvmKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: evm10.Methods,
state: new(evm10.State),
})
case manifest.EamKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: eam10.Methods,
state: nil,
})
case manifest.PlaceholderKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: placeholder10.Methods,
state: nil,
})
case manifest.EthAccountKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: ethaccount10.Methods,
state: nil,
})
}
}

View File

@ -25,6 +25,12 @@ import (
{{if (ge . 9)}}
datacap{{.}} "github.com/filecoin-project/go-state-types/builtin/v{{.}}/datacap"
{{end}}
{{if (ge . 10)}}
evm{{.}} "github.com/filecoin-project/go-state-types/builtin/v{{.}}/evm"
eam{{.}} "github.com/filecoin-project/go-state-types/builtin/v{{.}}/eam"
placeholder{{.}} "github.com/filecoin-project/go-state-types/builtin/v{{.}}/placeholder"
ethaccount{{.}} "github.com/filecoin-project/go-state-types/builtin/v{{.}}/ethaccount"
{{end}}
{{end}}
"github.com/filecoin-project/go-state-types/cbor"
rtt "github.com/filecoin-project/go-state-types/rt"
@ -174,6 +180,32 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry {
methods: datacap{{.}}.Methods,
state: new(datacap{{.}}.State),
}){{end}}
{{if (ge . 10)}}
case manifest.EvmKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: evm{{.}}.Methods,
state: new(evm{{.}}.State),
})
case manifest.EamKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: eam{{.}}.Methods,
state: nil,
})
case manifest.PlaceholderKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: placeholder{{.}}.Methods,
state: nil,
})
case manifest.EthAccountKey:
registry = append(registry, RegistryEntry{
code: codeID,
methods: ethaccount{{.}}.Methods,
state: nil,
})
{{end}}
}
}
{{end}}

View File

@ -10,11 +10,13 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
logging "github.com/ipfs/go-log/v2"
pubsub "github.com/libp2p/go-libp2p-pubsub"
"github.com/multiformats/go-varint"
cbg "github.com/whyrusleeping/cbor-gen"
"go.opencensus.io/stats"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
@ -29,7 +31,6 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/lib/async"
"github.com/filecoin-project/lotus/lib/sigs"
"github.com/filecoin-project/lotus/metrics"
)
@ -130,7 +131,39 @@ func CommonBlkChecks(ctx context.Context, sm *stmgr.StateManager, cs *store.Chai
}
}
// Check the validity of the messages included in a block.
func IsValidForSending(nv network.Version, act *types.Actor) bool {
// Before nv18 (Hygge), we only supported built-in account actors as senders.
//
// Note: this gate is probably superfluous, since:
// 1. Placeholder actors cannot be created before nv18.
// 2. EthAccount actors cannot be created before nv18.
// 3. Delegated addresses cannot be created before nv18.
//
// But it's a safeguard.
//
// Note 2: ad-hoc checks for network versions like this across the codebase
// will be problematic with networks with diverging version lineages
// (e.g. Hyperspace). We need to revisit this strategy entirely.
if nv < network.Version18 {
return builtin.IsAccountActor(act.Code)
}
// After nv18, we also support other kinds of senders.
if builtin.IsAccountActor(act.Code) || builtin.IsEthAccountActor(act.Code) {
return true
}
// Allow placeholder actors with a delegated address and nonce 0 to send a message.
// These will be converted to an EthAccount actor on first send.
if !builtin.IsPlaceholderActor(act.Code) || act.Nonce != 0 || act.Address == nil || act.Address.Protocol() != address.Delegated {
return false
}
// Only allow such actors to send if their delegated address is in the EAM's namespace.
id, _, err := varint.FromUvarint(act.Address.Payload())
return err == nil && id == builtintypes.EthereumAddressManagerActorID
}
func checkBlockMessages(ctx context.Context, sm *stmgr.StateManager, cs *store.ChainStore, b *types.FullBlock, baseTs *types.TipSet) error {
{
var sigCids []cid.Cid // this is what we get for people not wanting the marshalcbor method on the cid type
@ -202,7 +235,7 @@ func checkBlockMessages(ctx context.Context, sm *stmgr.StateManager, cs *store.C
return xerrors.Errorf("failed to get actor: %w", err)
}
if !builtin.IsAccountActor(act.Code) {
if !IsValidForSending(nv, act) {
return xerrors.New("Sender must be an account actor")
}
nonces[sender] = act.Nonce
@ -239,25 +272,23 @@ func checkBlockMessages(ctx context.Context, sm *stmgr.StateManager, cs *store.C
smArr := blockadt.MakeEmptyArray(tmpstore)
for i, m := range b.SecpkMessages {
if sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version14 {
if m.Signature.Type != crypto.SigTypeSecp256k1 {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
if nv >= network.Version14 && !IsValidSecpkSigType(nv, m.Signature.Type) {
return xerrors.Errorf("block had invalid signed message at index %d: %w", i, err)
}
if err := checkMsg(m); err != nil {
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
// `From` being an account actor is only validated inside the `vm.ResolveToKeyAddr` call
// in `StateManager.ResolveToKeyAddress` here (and not in `checkMsg`).
kaddr, err := sm.ResolveToKeyAddress(ctx, m.Message.From, baseTs)
// `From` being an account actor is only validated inside the `vm.ResolveToDeterministicAddr` call
// in `StateManager.ResolveToDeterministicAddress` here (and not in `checkMsg`).
kaddr, err := sm.ResolveToDeterministicAddress(ctx, m.Message.From, baseTs)
if err != nil {
return xerrors.Errorf("failed to resolve key addr: %w", err)
}
if err := sigs.Verify(&m.Signature, kaddr, m.Message.Cid().Bytes()); err != nil {
return xerrors.Errorf("secpk message %s has invalid signature: %w", m.Cid(), err)
if err := AuthenticateMessage(m, kaddr); err != nil {
return xerrors.Errorf("failed to validate signature: %w", err)
}
c, err := store.PutMessage(ctx, tmpbs, m)
@ -330,6 +361,7 @@ func CreateBlockHeader(ctx context.Context, sm *stmgr.StateManager, pts *types.T
var blsMsgCids, secpkMsgCids []cid.Cid
var blsSigs []crypto.Signature
nv := sm.GetNetworkVersion(ctx, bt.Epoch)
for _, msg := range bt.Messages {
if msg.Signature.Type == crypto.SigTypeBLS {
blsSigs = append(blsSigs, msg.Signature)
@ -341,7 +373,7 @@ func CreateBlockHeader(ctx context.Context, sm *stmgr.StateManager, pts *types.T
}
blsMsgCids = append(blsMsgCids, c)
} else if msg.Signature.Type == crypto.SigTypeSecp256k1 {
} else if IsValidSecpkSigType(nv, msg.Signature.Type) {
c, err := sm.ChainStore().PutMessage(ctx, msg)
if err != nil {
return nil, nil, nil, err

View File

@ -94,6 +94,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: e,
Timestamp: ts.MinTimestamp(),
Rand: r,
Bstore: sm.ChainStore().StateBlockstore(),
Actors: NewActorRegistry(),

View File

@ -18,8 +18,10 @@ import (
"github.com/filecoin-project/go-state-types/abi"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/big"
nv18 "github.com/filecoin-project/go-state-types/builtin/v10/migration"
nv17 "github.com/filecoin-project/go-state-types/builtin/v9/migration"
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/go-state-types/migration"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/go-state-types/rt"
gstStore "github.com/filecoin-project/go-state-types/store"
@ -232,8 +234,18 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule {
StopWithin: 5,
}},
Expensive: true,
}, {
Height: build.UpgradeHyggeHeight,
Network: network.Version18,
Migration: UpgradeActorsV10,
PreMigrations: []stmgr.PreMigration{{
PreMigration: PreUpgradeActorsV10,
StartWithin: 180,
DontStartWithin: 60,
StopWithin: 5,
}},
Expensive: true,
},
// TODO v10 upgrade
}
for _, u := range updates {
@ -1580,11 +1592,110 @@ func upgradeActorsV9Common(
func UpgradeActorsV10(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, cb stmgr.ExecMonitor,
root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) (cid.Cid, error) {
// Use all the CPUs except 3.
workerCount := MigrationMaxWorkerCount - 3
if workerCount <= 0 {
workerCount = 1
}
// TODO migration
// - the init actor state to include the (empty) installed actors field
// - state tree migration to v5
return cid.Undef, fmt.Errorf("IMPLEMENTME: v10 migration")
config := migration.Config{
MaxWorkers: uint(workerCount),
JobQueueSize: 1000,
ResultQueueSize: 100,
ProgressLogPeriod: 10 * time.Second,
}
newRoot, err := upgradeActorsV10Common(ctx, sm, cache, root, epoch, ts, config)
if err != nil {
return cid.Undef, xerrors.Errorf("migrating actors v10 state: %w", err)
}
return newRoot, nil
}
func PreUpgradeActorsV10(ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache, root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet) error {
// Use half the CPUs for pre-migration, but leave at least 3.
workerCount := MigrationMaxWorkerCount
if workerCount <= 4 {
workerCount = 1
} else {
workerCount /= 2
}
lbts, lbRoot, err := stmgr.GetLookbackTipSetForRound(ctx, sm, ts, epoch)
if err != nil {
return xerrors.Errorf("error getting lookback ts for premigration: %w", err)
}
config := migration.Config{
MaxWorkers: uint(workerCount),
ProgressLogPeriod: time.Minute * 5,
}
_, err = upgradeActorsV10Common(ctx, sm, cache, lbRoot, epoch, lbts, config)
return err
}
func upgradeActorsV10Common(
ctx context.Context, sm *stmgr.StateManager, cache stmgr.MigrationCache,
root cid.Cid, epoch abi.ChainEpoch, ts *types.TipSet,
config migration.Config,
) (cid.Cid, error) {
buf := blockstore.NewTieredBstore(sm.ChainStore().StateBlockstore(), blockstore.NewMemorySync())
store := store.ActorStore(ctx, buf)
// ensure that the manifest is loaded in the blockstore
if err := bundle.LoadBundles(ctx, sm.ChainStore().StateBlockstore(), actorstypes.Version10); err != nil {
return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err)
}
// Load the state root.
var stateRoot types.StateRoot
if err := store.Get(ctx, root, &stateRoot); err != nil {
return cid.Undef, xerrors.Errorf("failed to decode state root: %w", err)
}
if stateRoot.Version != types.StateTreeVersion4 {
return cid.Undef, xerrors.Errorf(
"expected state root version 4 for actors v9 upgrade, got %d",
stateRoot.Version,
)
}
manifest, ok := actors.GetManifest(actorstypes.Version10)
if !ok {
return cid.Undef, xerrors.Errorf("no manifest CID for v9 upgrade")
}
// Perform the migration
newHamtRoot, err := nv18.MigrateStateTree(ctx, store, manifest, stateRoot.Actors, epoch, config,
migrationLogger{}, cache)
if err != nil {
return cid.Undef, xerrors.Errorf("upgrading to actors v10: %w", err)
}
// Persist the result.
newRoot, err := store.Put(ctx, &types.StateRoot{
Version: types.StateTreeVersion5,
Actors: newHamtRoot,
Info: stateRoot.Info,
})
if err != nil {
return cid.Undef, xerrors.Errorf("failed to persist new state root: %w", err)
}
// Persist the new tree.
{
from := buf
to := buf.Read()
if err := vm.Copy(ctx, from, to, newRoot); err != nil {
return cid.Undef, xerrors.Errorf("copying migrated tree: %w", err)
}
}
return newRoot, nil
}
// Example upgrade function if upgrade requires only code changes

View File

@ -0,0 +1,62 @@
package consensus
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/lib/sigs"
)
// AuthenticateMessage authenticates the message by verifying that the supplied
// SignedMessage was signed by the indicated Address, computing the correct
// signature payload depending on the signature type. The supplied Address type
// must be recognized by the registered verifier for the signature type.
func AuthenticateMessage(msg *types.SignedMessage, signer address.Address) error {
var digest []byte
typ := msg.Signature.Type
switch typ {
case crypto.SigTypeDelegated:
txArgs, err := ethtypes.EthTxArgsFromMessage(&msg.Message)
if err != nil {
return xerrors.Errorf("failed to reconstruct eth transaction: %w", err)
}
roundTripMsg, err := txArgs.ToUnsignedMessage(msg.Message.From)
if err != nil {
return xerrors.Errorf("failed to reconstruct filecoin msg: %w", err)
}
if !msg.Message.Equals(roundTripMsg) {
return xerrors.New("ethereum tx failed to roundtrip")
}
rlpEncodedMsg, err := txArgs.ToRlpUnsignedMsg()
if err != nil {
return xerrors.Errorf("failed to repack eth rlp message: %w", err)
}
digest = rlpEncodedMsg
default:
digest = msg.Message.Cid().Bytes()
}
if err := sigs.Verify(&msg.Signature, signer, digest); err != nil {
return xerrors.Errorf("message %s has invalid signature (type %d): %w", msg.Cid(), typ, err)
}
return nil
}
// IsValidSecpkSigType checks that a signature type is valid for the network
// version, for a "secpk" message.
func IsValidSecpkSigType(nv network.Version, typ crypto.SigType) bool {
switch {
case nv < network.Version18:
return typ == crypto.SigTypeSecp256k1
default:
return typ == crypto.SigTypeSecp256k1 || typ == crypto.SigTypeDelegated
}
}

View File

@ -0,0 +1,474 @@
package filter
import (
"bytes"
"context"
"math"
"sync"
"time"
"github.com/ipfs/go-cid"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
amt4 "github.com/filecoin-project/go-amt-ipld/v4"
"github.com/filecoin-project/go-state-types/abi"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
cstore "github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
)
const indexed uint8 = 0x01
type EventFilter struct {
id types.FilterID
minHeight abi.ChainEpoch // minimum epoch to apply filter or -1 if no minimum
maxHeight abi.ChainEpoch // maximum epoch to apply filter or -1 if no maximum
tipsetCid cid.Cid
addresses []address.Address // list of f4 actor addresses that are extpected to emit the event
keys map[string][][]byte // map of key names to a list of alternate values that may match
maxResults int // maximum number of results to collect, 0 is unlimited
mu sync.Mutex
collected []*CollectedEvent
lastTaken time.Time
ch chan<- interface{}
}
var _ Filter = (*EventFilter)(nil)
type CollectedEvent struct {
Entries []types.EventEntry
EmitterAddr address.Address // f4 address of emitter
EventIdx int // index of the event within the list of emitted events
Reverted bool
Height abi.ChainEpoch
TipSetKey types.TipSetKey // tipset that contained the message
MsgIdx int // index of the message in the tipset
MsgCid cid.Cid // cid of message that produced event
}
func (f *EventFilter) ID() types.FilterID {
return f.id
}
func (f *EventFilter) SetSubChannel(ch chan<- interface{}) {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = ch
f.collected = nil
}
func (f *EventFilter) ClearSubChannel() {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = nil
}
func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, revert bool, resolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool)) error {
if !f.matchTipset(te) {
return nil
}
// cache of lookups between actor id and f4 address
addressLookups := make(map[abi.ActorID]address.Address)
ems, err := te.messages(ctx)
if err != nil {
return xerrors.Errorf("load executed messages: %w", err)
}
for msgIdx, em := range ems {
for evIdx, ev := range em.Events() {
// lookup address corresponding to the actor id
addr, found := addressLookups[ev.Emitter]
if !found {
var ok bool
addr, ok = resolver(ctx, ev.Emitter, te.rctTs)
if !ok {
// not an address we will be able to match against
continue
}
addressLookups[ev.Emitter] = addr
}
if !f.matchAddress(addr) {
continue
}
if !f.matchKeys(ev.Entries) {
continue
}
// event matches filter, so record it
cev := &CollectedEvent{
Entries: ev.Entries,
EmitterAddr: addr,
EventIdx: evIdx,
Reverted: revert,
Height: te.msgTs.Height(),
TipSetKey: te.msgTs.Key(),
MsgCid: em.Message().Cid(),
MsgIdx: msgIdx,
}
f.mu.Lock()
// if we have a subscription channel then push event to it
if f.ch != nil {
f.ch <- cev
f.mu.Unlock()
continue
}
if f.maxResults > 0 && len(f.collected) == f.maxResults {
copy(f.collected, f.collected[1:])
f.collected = f.collected[:len(f.collected)-1]
}
f.collected = append(f.collected, cev)
f.mu.Unlock()
}
}
return nil
}
func (f *EventFilter) setCollectedEvents(ces []*CollectedEvent) {
f.mu.Lock()
f.collected = ces
f.mu.Unlock()
}
func (f *EventFilter) TakeCollectedEvents(ctx context.Context) []*CollectedEvent {
f.mu.Lock()
collected := f.collected
f.collected = nil
f.lastTaken = time.Now().UTC()
f.mu.Unlock()
return collected
}
func (f *EventFilter) LastTaken() time.Time {
f.mu.Lock()
defer f.mu.Unlock()
return f.lastTaken
}
// matchTipset reports whether this filter matches the given tipset
func (f *EventFilter) matchTipset(te *TipSetEvents) bool {
if f.tipsetCid != cid.Undef {
tsCid, err := te.Cid()
if err != nil {
return false
}
return f.tipsetCid.Equals(tsCid)
}
if f.minHeight >= 0 && f.minHeight > te.Height() {
return false
}
if f.maxHeight >= 0 && f.maxHeight < te.Height() {
return false
}
return true
}
func (f *EventFilter) matchAddress(o address.Address) bool {
if len(f.addresses) == 0 {
return true
}
// Assume short lists of addresses
// TODO: binary search for longer lists or restrict list length
for _, a := range f.addresses {
if a == o {
return true
}
}
return false
}
func (f *EventFilter) matchKeys(ees []types.EventEntry) bool {
if len(f.keys) == 0 {
return true
}
// TODO: optimize this naive algorithm
// tracked in https://github.com/filecoin-project/lotus/issues/9987
// Note keys names may be repeated so we may have multiple opportunities to match
matched := map[string]bool{}
for _, ee := range ees {
// Skip an entry that is not indexable
if ee.Flags&indexed != indexed {
continue
}
keyname := ee.Key
// skip if we have already matched this key
if matched[keyname] {
continue
}
wantlist, ok := f.keys[keyname]
if !ok {
continue
}
for _, w := range wantlist {
if bytes.Equal(w, ee.Value) {
matched[keyname] = true
break
}
}
if len(matched) == len(f.keys) {
// all keys have been matched
return true
}
}
return false
}
type TipSetEvents struct {
rctTs *types.TipSet // rctTs is the tipset containing the receipts of executed messages
msgTs *types.TipSet // msgTs is the tipset containing the messages that have been executed
load func(ctx context.Context, msgTs, rctTs *types.TipSet) ([]executedMessage, error)
once sync.Once // for lazy population of ems
ems []executedMessage
err error
}
func (te *TipSetEvents) Height() abi.ChainEpoch {
return te.msgTs.Height()
}
func (te *TipSetEvents) Cid() (cid.Cid, error) {
return te.msgTs.Key().Cid()
}
func (te *TipSetEvents) messages(ctx context.Context) ([]executedMessage, error) {
te.once.Do(func() {
// populate executed message list
ems, err := te.load(ctx, te.msgTs, te.rctTs)
if err != nil {
te.err = err
return
}
te.ems = ems
})
return te.ems, te.err
}
type executedMessage struct {
msg *types.Message
rct *types.MessageReceipt
// events extracted from receipt
evs []*types.Event
}
func (e *executedMessage) Message() *types.Message {
return e.msg
}
func (e *executedMessage) Receipt() *types.MessageReceipt {
return e.rct
}
func (e *executedMessage) Events() []*types.Event {
return e.evs
}
type EventFilterManager struct {
ChainStore *cstore.ChainStore
AddressResolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool)
MaxFilterResults int
EventIndex *EventIndex
mu sync.Mutex // guards mutations to filters
filters map[types.FilterID]*EventFilter
currentHeight abi.ChainEpoch
}
func (m *EventFilterManager) Apply(ctx context.Context, from, to *types.TipSet) error {
m.mu.Lock()
defer m.mu.Unlock()
m.currentHeight = to.Height()
if len(m.filters) == 0 && m.EventIndex == nil {
return nil
}
tse := &TipSetEvents{
msgTs: from,
rctTs: to,
load: m.loadExecutedMessages,
}
if m.EventIndex != nil {
if err := m.EventIndex.CollectEvents(ctx, tse, false, m.AddressResolver); err != nil {
return err
}
}
// TODO: could run this loop in parallel with errgroup if there are many filters
for _, f := range m.filters {
if err := f.CollectEvents(ctx, tse, false, m.AddressResolver); err != nil {
return err
}
}
return nil
}
func (m *EventFilterManager) Revert(ctx context.Context, from, to *types.TipSet) error {
m.mu.Lock()
defer m.mu.Unlock()
m.currentHeight = to.Height()
if len(m.filters) == 0 && m.EventIndex == nil {
return nil
}
tse := &TipSetEvents{
msgTs: to,
rctTs: from,
load: m.loadExecutedMessages,
}
if m.EventIndex != nil {
if err := m.EventIndex.CollectEvents(ctx, tse, true, m.AddressResolver); err != nil {
return err
}
}
// TODO: could run this loop in parallel with errgroup if there are many filters
for _, f := range m.filters {
if err := f.CollectEvents(ctx, tse, true, m.AddressResolver); err != nil {
return err
}
}
return nil
}
func (m *EventFilterManager) Install(ctx context.Context, minHeight, maxHeight abi.ChainEpoch, tipsetCid cid.Cid, addresses []address.Address, keys map[string][][]byte) (*EventFilter, error) {
m.mu.Lock()
currentHeight := m.currentHeight
m.mu.Unlock()
if m.EventIndex == nil && minHeight != -1 && minHeight < currentHeight {
return nil, xerrors.Errorf("historic event index disabled")
}
id, err := newFilterID()
if err != nil {
return nil, xerrors.Errorf("new filter id: %w", err)
}
f := &EventFilter{
id: id,
minHeight: minHeight,
maxHeight: maxHeight,
tipsetCid: tipsetCid,
addresses: addresses,
keys: keys,
maxResults: m.MaxFilterResults,
}
if m.EventIndex != nil && minHeight != -1 && minHeight < currentHeight {
// Filter needs historic events
if err := m.EventIndex.PrefillFilter(ctx, f); err != nil {
return nil, err
}
}
m.mu.Lock()
if m.filters == nil {
m.filters = make(map[types.FilterID]*EventFilter)
}
m.filters[id] = f
m.mu.Unlock()
return f, nil
}
func (m *EventFilterManager) Remove(ctx context.Context, id types.FilterID) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, found := m.filters[id]; !found {
return ErrFilterNotFound
}
delete(m.filters, id)
return nil
}
func (m *EventFilterManager) loadExecutedMessages(ctx context.Context, msgTs, rctTs *types.TipSet) ([]executedMessage, error) {
msgs, err := m.ChainStore.MessagesForTipset(ctx, msgTs)
if err != nil {
return nil, xerrors.Errorf("read messages: %w", err)
}
st := m.ChainStore.ActorStore(ctx)
arr, err := blockadt.AsArray(st, rctTs.Blocks()[0].ParentMessageReceipts)
if err != nil {
return nil, xerrors.Errorf("load receipts amt: %w", err)
}
if uint64(len(msgs)) != arr.Length() {
return nil, xerrors.Errorf("mismatching message and receipt counts (%d msgs, %d rcts)", len(msgs), arr.Length())
}
ems := make([]executedMessage, len(msgs))
for i := 0; i < len(msgs); i++ {
ems[i].msg = msgs[i].VMMessage()
var rct types.MessageReceipt
found, err := arr.Get(uint64(i), &rct)
if err != nil {
return nil, xerrors.Errorf("load receipt: %w", err)
}
if !found {
return nil, xerrors.Errorf("receipt %d not found", i)
}
ems[i].rct = &rct
if rct.EventsRoot == nil {
continue
}
evtArr, err := amt4.LoadAMT(ctx, st, *rct.EventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth))
if err != nil {
return nil, xerrors.Errorf("load events amt: %w", err)
}
ems[i].evs = make([]*types.Event, evtArr.Len())
var evt types.Event
err = evtArr.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error {
if u > math.MaxInt {
return xerrors.Errorf("too many events")
}
if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil {
return err
}
cpy := evt
ems[i].evs[int(u)] = &cpy //nolint:scopelint
return nil
})
if err != nil {
return nil, xerrors.Errorf("read events: %w", err)
}
}
return ems, nil
}

View File

@ -0,0 +1,431 @@
package filter
import (
"context"
pseudo "math/rand"
"testing"
"github.com/ipfs/go-cid"
cbor "github.com/ipfs/go-ipld-cbor"
mh "github.com/multiformats/go-multihash"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/exitcode"
blockadt "github.com/filecoin-project/specs-actors/actors/util/adt"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/chain/actors/adt"
"github.com/filecoin-project/lotus/chain/types"
)
func TestEventFilterCollectEvents(t *testing.T) {
rng := pseudo.New(pseudo.NewSource(299792458))
a1 := randomF4Addr(t, rng)
a2 := randomF4Addr(t, rng)
a1ID := abi.ActorID(1)
a2ID := abi.ActorID(2)
addrMap := addressMap{}
addrMap.add(a1ID, a1)
addrMap.add(a2ID, a2)
ev1 := fakeEvent(
a1ID,
[]kv{
{k: "type", v: []byte("approval")},
{k: "signer", v: []byte("addr1")},
},
[]kv{
{k: "amount", v: []byte("2988181")},
},
)
st := newStore()
events := []*types.Event{ev1}
em := executedMessage{
msg: fakeMessage(randomF4Addr(t, rng), randomF4Addr(t, rng)),
rct: fakeReceipt(t, rng, st, events),
evs: events,
}
events14000 := buildTipSetEvents(t, rng, 14000, em)
cid14000, err := events14000.msgTs.Key().Cid()
require.NoError(t, err, "tipset cid")
noCollectedEvents := []*CollectedEvent{}
oneCollectedEvent := []*CollectedEvent{
{
Entries: ev1.Entries,
EmitterAddr: a1,
EventIdx: 0,
Reverted: false,
Height: 14000,
TipSetKey: events14000.msgTs.Key(),
MsgIdx: 0,
MsgCid: em.msg.Cid(),
},
}
testCases := []struct {
name string
filter *EventFilter
te *TipSetEvents
want []*CollectedEvent
}{
{
name: "nomatch tipset min height",
filter: &EventFilter{
minHeight: 14001,
maxHeight: -1,
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch tipset max height",
filter: &EventFilter{
minHeight: -1,
maxHeight: 13999,
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match tipset min height",
filter: &EventFilter{
minHeight: 14000,
maxHeight: -1,
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match tipset cid",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
tipsetCid: cid14000,
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch address",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
addresses: []address.Address{a2},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match address",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
addresses: []address.Address{a1},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match one entry",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match one entry with alternate values",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("cancel"),
[]byte("propose"),
[]byte("approval"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch one entry by missing value",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("cancel"),
[]byte("propose"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry by missing key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"method": {
[]byte("approval"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match one entry with multiple keys",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"signer": {
[]byte("addr1"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch one entry with one mismatching key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"approver": {
[]byte("addr1"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry with one mismatching value",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"signer": {
[]byte("addr2"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry with one unindexed key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"amount": {
[]byte("2988181"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
}
for _, tc := range testCases {
tc := tc // appease lint
t.Run(tc.name, func(t *testing.T) {
if err := tc.filter.CollectEvents(context.Background(), tc.te, false, addrMap.ResolveAddress); err != nil {
require.NoError(t, err, "collect events")
}
coll := tc.filter.TakeCollectedEvents(context.Background())
require.ElementsMatch(t, coll, tc.want)
})
}
}
type kv struct {
k string
v []byte
}
func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event {
ev := &types.Event{
Emitter: emitter,
}
for _, in := range indexed {
ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x01,
Key: in.k,
Value: in.v,
})
}
for _, in := range unindexed {
ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x00,
Key: in.k,
Value: in.v,
})
}
return ev
}
func randomF4Addr(tb testing.TB, rng *pseudo.Rand) address.Address {
tb.Helper()
addr, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, randomBytes(32, rng))
require.NoError(tb, err)
return addr
}
func randomIDAddr(tb testing.TB, rng *pseudo.Rand) address.Address {
tb.Helper()
addr, err := address.NewIDAddress(uint64(rng.Int63()))
require.NoError(tb, err)
return addr
}
func randomCid(tb testing.TB, rng *pseudo.Rand) cid.Cid {
tb.Helper()
cb := cid.V1Builder{Codec: cid.Raw, MhType: mh.IDENTITY}
c, err := cb.Sum(randomBytes(10, rng))
require.NoError(tb, err)
return c
}
func randomBytes(n int, rng *pseudo.Rand) []byte {
buf := make([]byte, n)
rng.Read(buf)
return buf
}
func fakeMessage(to, from address.Address) *types.Message {
return &types.Message{
To: to,
From: from,
Nonce: 197,
Method: 1,
Params: []byte("some random bytes"),
GasLimit: 126723,
GasPremium: types.NewInt(4),
GasFeeCap: types.NewInt(120),
}
}
func fakeReceipt(tb testing.TB, rng *pseudo.Rand, st adt.Store, events []*types.Event) *types.MessageReceipt {
arr := blockadt.MakeEmptyArray(st)
for _, ev := range events {
err := arr.AppendContinuous(ev)
require.NoError(tb, err, "append event")
}
eventsRoot, err := arr.Root()
require.NoError(tb, err, "flush events amt")
rec := types.NewMessageReceiptV1(exitcode.Ok, randomBytes(32, rng), rng.Int63(), &eventsRoot)
return &rec
}
func fakeTipSet(tb testing.TB, rng *pseudo.Rand, h abi.ChainEpoch, parents []cid.Cid) *types.TipSet {
tb.Helper()
ts, err := types.NewTipSet([]*types.BlockHeader{
{
Height: h,
Miner: randomIDAddr(tb, rng),
Parents: parents,
Ticket: &types.Ticket{VRFProof: []byte{byte(h % 2)}},
ParentStateRoot: randomCid(tb, rng),
Messages: randomCid(tb, rng),
ParentMessageReceipts: randomCid(tb, rng),
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
},
{
Height: h,
Miner: randomIDAddr(tb, rng),
Parents: parents,
Ticket: &types.Ticket{VRFProof: []byte{byte((h + 1) % 2)}},
ParentStateRoot: randomCid(tb, rng),
Messages: randomCid(tb, rng),
ParentMessageReceipts: randomCid(tb, rng),
BlockSig: &crypto.Signature{Type: crypto.SigTypeBLS},
BLSAggregate: &crypto.Signature{Type: crypto.SigTypeBLS},
},
})
require.NoError(tb, err)
return ts
}
func newStore() adt.Store {
ctx := context.Background()
bs := blockstore.NewMemorySync()
store := cbor.NewCborStore(bs)
return adt.WrapStore(ctx, store)
}
func buildTipSetEvents(tb testing.TB, rng *pseudo.Rand, h abi.ChainEpoch, em executedMessage) *TipSetEvents {
tb.Helper()
msgTs := fakeTipSet(tb, rng, h, []cid.Cid{})
rctTs := fakeTipSet(tb, rng, h+1, msgTs.Cids())
return &TipSetEvents{
msgTs: msgTs,
rctTs: rctTs,
load: func(ctx context.Context, msgTs, rctTs *types.TipSet) ([]executedMessage, error) {
return []executedMessage{em}, nil
},
}
}
type addressMap map[abi.ActorID]address.Address
func (a addressMap) add(actorID abi.ActorID, addr address.Address) {
a[actorID] = addr
}
func (a addressMap) ResolveAddress(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) {
ra, ok := a[emitter]
return ra, ok
}

View File

@ -0,0 +1,434 @@
package filter
import (
"bytes"
"context"
"database/sql"
"errors"
"fmt"
"sort"
"strings"
"github.com/ipfs/go-cid"
_ "github.com/mattn/go-sqlite3"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
)
var pragmas = []string{
"PRAGMA synchronous = normal",
"PRAGMA temp_store = memory",
"PRAGMA mmap_size = 30000000000",
"PRAGMA page_size = 32768",
"PRAGMA auto_vacuum = NONE",
"PRAGMA automatic_index = OFF",
"PRAGMA journal_mode = WAL",
"PRAGMA read_uncommitted = ON",
}
var ddls = []string{
`CREATE TABLE IF NOT EXISTS event (
id INTEGER PRIMARY KEY,
height INTEGER NOT NULL,
tipset_key BLOB NOT NULL,
tipset_key_cid BLOB NOT NULL,
emitter_addr BLOB NOT NULL,
event_index INTEGER NOT NULL,
message_cid BLOB NOT NULL,
message_index INTEGER NOT NULL,
reverted INTEGER NOT NULL
)`,
`CREATE TABLE IF NOT EXISTS event_entry (
event_id INTEGER,
indexed INTEGER NOT NULL,
flags BLOB NOT NULL,
key TEXT NOT NULL,
value BLOB NOT NULL
)`,
// metadata containing version of schema
`CREATE TABLE IF NOT EXISTS _meta (
version UINT64 NOT NULL UNIQUE
)`,
// version 1.
`INSERT OR IGNORE INTO _meta (version) VALUES (1)`,
}
const schemaVersion = 1
const (
insertEvent = `INSERT OR IGNORE INTO event
(height, tipset_key, tipset_key_cid, emitter_addr, event_index, message_cid, message_index, reverted)
VALUES(?, ?, ?, ?, ?, ?, ?, ?)`
insertEntry = `INSERT OR IGNORE INTO event_entry
(event_id, indexed, flags, key, value)
VALUES(?, ?, ?, ?, ?)`
)
type EventIndex struct {
db *sql.DB
}
func NewEventIndex(path string) (*EventIndex, error) {
db, err := sql.Open("sqlite3", path+"?mode=rwc")
if err != nil {
return nil, xerrors.Errorf("open sqlite3 database: %w", err)
}
for _, pragma := range pragmas {
if _, err := db.Exec(pragma); err != nil {
_ = db.Close()
return nil, xerrors.Errorf("exec pragma %q: %w", pragma, err)
}
}
q, err := db.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='_meta';")
if err == sql.ErrNoRows || !q.Next() {
// empty database, create the schema
for _, ddl := range ddls {
if _, err := db.Exec(ddl); err != nil {
_ = db.Close()
return nil, xerrors.Errorf("exec ddl %q: %w", ddl, err)
}
}
} else if err != nil {
_ = db.Close()
return nil, xerrors.Errorf("looking for _meta table: %w", err)
} else {
// Ensure we don't open a database from a different schema version
row := db.QueryRow("SELECT max(version) FROM _meta")
var version int
err := row.Scan(&version)
if err != nil {
_ = db.Close()
return nil, xerrors.Errorf("invalid database version: no version found")
}
if version != schemaVersion {
_ = db.Close()
return nil, xerrors.Errorf("invalid database version: got %d, expected %d", version, schemaVersion)
}
}
return &EventIndex{
db: db,
}, nil
}
func (ei *EventIndex) Close() error {
if ei.db == nil {
return nil
}
return ei.db.Close()
}
func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, revert bool, resolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool)) error {
// cache of lookups between actor id and f4 address
addressLookups := make(map[abi.ActorID]address.Address)
ems, err := te.messages(ctx)
if err != nil {
return xerrors.Errorf("load executed messages: %w", err)
}
tx, err := ei.db.Begin()
if err != nil {
return xerrors.Errorf("begin transaction: %w", err)
}
stmtEvent, err := tx.Prepare(insertEvent)
if err != nil {
return xerrors.Errorf("prepare insert event: %w", err)
}
stmtEntry, err := tx.Prepare(insertEntry)
if err != nil {
return xerrors.Errorf("prepare insert entry: %w", err)
}
isIndexedValue := func(b uint8) bool {
// currently we mark the full entry as indexed if either the key
// or the value are indexed; in the future we will need finer-grained
// management of indices
return b&(types.EventFlagIndexedKey|types.EventFlagIndexedValue) > 0
}
for msgIdx, em := range ems {
for evIdx, ev := range em.Events() {
addr, found := addressLookups[ev.Emitter]
if !found {
var ok bool
addr, ok = resolver(ctx, ev.Emitter, te.rctTs)
if !ok {
// not an address we will be able to match against
continue
}
addressLookups[ev.Emitter] = addr
}
tsKeyCid, err := te.msgTs.Key().Cid()
if err != nil {
return xerrors.Errorf("tipset key cid: %w", err)
}
res, err := stmtEvent.Exec(
te.msgTs.Height(), // height
te.msgTs.Key().Bytes(), // tipset_key
tsKeyCid.Bytes(), // tipset_key_cid
addr.Bytes(), // emitter_addr
evIdx, // event_index
em.Message().Cid().Bytes(), // message_cid
msgIdx, // message_index
revert, // reverted
)
if err != nil {
return xerrors.Errorf("exec insert event: %w", err)
}
lastID, err := res.LastInsertId()
if err != nil {
return xerrors.Errorf("get last row id: %w", err)
}
for _, entry := range ev.Entries {
value := decodeLogBytes(entry.Value)
_, err := stmtEntry.Exec(
lastID, // event_id
isIndexedValue(entry.Flags), // indexed
[]byte{entry.Flags}, // flags
entry.Key, // key
value, // value
)
if err != nil {
return xerrors.Errorf("exec insert entry: %w", err)
}
}
}
}
if err := tx.Commit(); err != nil {
return xerrors.Errorf("commit transaction: %w", err)
}
return nil
}
// decodeLogBytes decodes a CBOR-serialized array into its original form.
//
// This function swallows errors and returns the original array if it failed
// to decode.
func decodeLogBytes(orig []byte) []byte {
if orig == nil {
return orig
}
decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig)))
if err != nil {
return orig
}
return decoded
}
// PrefillFilter fills a filter's collection of events from the historic index
func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
clauses := []string{}
values := []any{}
joins := []string{}
if f.tipsetCid != cid.Undef {
clauses = append(clauses, "event.tipset_key_cid=?")
values = append(values, f.tipsetCid.Bytes())
} else {
if f.minHeight >= 0 {
clauses = append(clauses, "event.height>=?")
values = append(values, f.minHeight)
}
if f.maxHeight >= 0 {
clauses = append(clauses, "event.height<=?")
values = append(values, f.maxHeight)
}
}
if len(f.addresses) > 0 {
subclauses := []string{}
for _, addr := range f.addresses {
subclauses = append(subclauses, "emitter_addr=?")
values = append(values, addr.Bytes())
}
clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")")
}
if len(f.keys) > 0 {
join := 0
for key, vals := range f.keys {
if len(vals) > 0 {
join++
joinAlias := fmt.Sprintf("ee%d", join)
joins = append(joins, fmt.Sprintf("event_entry %s on event.id=%[1]s.event_id", joinAlias))
clauses = append(clauses, fmt.Sprintf("%s.indexed=1 AND %[1]s.key=?", joinAlias))
values = append(values, key)
subclauses := []string{}
for _, val := range vals {
subclauses = append(subclauses, fmt.Sprintf("%s.value=?", joinAlias))
values = append(values, trimLeadingZeros(val))
}
clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")")
}
}
}
s := `SELECT
event.id,
event.height,
event.tipset_key,
event.tipset_key_cid,
event.emitter_addr,
event.event_index,
event.message_cid,
event.message_index,
event.reverted,
event_entry.flags,
event_entry.key,
event_entry.value
FROM event JOIN event_entry ON event.id=event_entry.event_id`
if len(joins) > 0 {
s = s + ", " + strings.Join(joins, ", ")
}
if len(clauses) > 0 {
s = s + " WHERE " + strings.Join(clauses, " AND ")
}
s += " ORDER BY event.height DESC"
stmt, err := ei.db.Prepare(s)
if err != nil {
return xerrors.Errorf("prepare prefill query: %w", err)
}
q, err := stmt.QueryContext(ctx, values...)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil
}
return xerrors.Errorf("exec prefill query: %w", err)
}
var ces []*CollectedEvent
var currentID int64 = -1
var ce *CollectedEvent
for q.Next() {
select {
case <-ctx.Done():
return ctx.Err()
default:
}
var row struct {
id int64
height uint64
tipsetKey []byte
tipsetKeyCid []byte
emitterAddr []byte
eventIndex int
messageCid []byte
messageIndex int
reverted bool
flags []byte
key string
value []byte
}
if err := q.Scan(
&row.id,
&row.height,
&row.tipsetKey,
&row.tipsetKeyCid,
&row.emitterAddr,
&row.eventIndex,
&row.messageCid,
&row.messageIndex,
&row.reverted,
&row.flags,
&row.key,
&row.value,
); err != nil {
return xerrors.Errorf("read prefill row: %w", err)
}
if row.id != currentID {
if ce != nil {
ces = append(ces, ce)
ce = nil
// Unfortunately we can't easily incorporate the max results limit into the query due to the
// unpredictable number of rows caused by joins
// Break here to stop collecting rows
if f.maxResults > 0 && len(ces) >= f.maxResults {
break
}
}
currentID = row.id
ce = &CollectedEvent{
EventIdx: row.eventIndex,
Reverted: row.reverted,
Height: abi.ChainEpoch(row.height),
MsgIdx: row.messageIndex,
}
ce.EmitterAddr, err = address.NewFromBytes(row.emitterAddr)
if err != nil {
return xerrors.Errorf("parse emitter addr: %w", err)
}
ce.TipSetKey, err = types.TipSetKeyFromBytes(row.tipsetKey)
if err != nil {
return xerrors.Errorf("parse tipsetkey: %w", err)
}
ce.MsgCid, err = cid.Cast(row.messageCid)
if err != nil {
return xerrors.Errorf("parse message cid: %w", err)
}
}
ce.Entries = append(ce.Entries, types.EventEntry{
Flags: row.flags[0],
Key: row.key,
Value: row.value,
})
}
if ce != nil {
ces = append(ces, ce)
}
if len(ces) == 0 {
return nil
}
// collected event list is in inverted order since we selected only the most recent events
// sort it into height order
sort.Slice(ces, func(i, j int) bool { return ces[i].Height < ces[j].Height })
f.setCollectedEvents(ces)
return nil
}
func trimLeadingZeros(b []byte) []byte {
for i := range b {
if b[i] != 0 {
return b[i:]
}
}
return []byte{}
}

View File

@ -0,0 +1,283 @@
package filter
import (
"context"
pseudo "math/rand"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/lotus/chain/types"
)
func TestEventIndexPrefillFilter(t *testing.T) {
rng := pseudo.New(pseudo.NewSource(299792458))
a1 := randomF4Addr(t, rng)
a2 := randomF4Addr(t, rng)
a1ID := abi.ActorID(1)
a2ID := abi.ActorID(2)
addrMap := addressMap{}
addrMap.add(a1ID, a1)
addrMap.add(a2ID, a2)
ev1 := fakeEvent(
a1ID,
[]kv{
{k: "type", v: []byte("approval")},
{k: "signer", v: []byte("addr1")},
},
[]kv{
{k: "amount", v: []byte("2988181")},
},
)
st := newStore()
events := []*types.Event{ev1}
em := executedMessage{
msg: fakeMessage(randomF4Addr(t, rng), randomF4Addr(t, rng)),
rct: fakeReceipt(t, rng, st, events),
evs: events,
}
events14000 := buildTipSetEvents(t, rng, 14000, em)
cid14000, err := events14000.msgTs.Key().Cid()
require.NoError(t, err, "tipset cid")
noCollectedEvents := []*CollectedEvent{}
oneCollectedEvent := []*CollectedEvent{
{
Entries: ev1.Entries,
EmitterAddr: a1,
EventIdx: 0,
Reverted: false,
Height: 14000,
TipSetKey: events14000.msgTs.Key(),
MsgIdx: 0,
MsgCid: em.msg.Cid(),
},
}
workDir, err := os.MkdirTemp("", "lotusevents")
require.NoError(t, err, "create temporary work directory")
defer func() {
_ = os.RemoveAll(workDir)
}()
t.Logf("using work dir %q", workDir)
dbPath := filepath.Join(workDir, "actorevents.db")
ei, err := NewEventIndex(dbPath)
require.NoError(t, err, "create event index")
if err := ei.CollectEvents(context.Background(), events14000, false, addrMap.ResolveAddress); err != nil {
require.NoError(t, err, "collect events")
}
testCases := []struct {
name string
filter *EventFilter
te *TipSetEvents
want []*CollectedEvent
}{
{
name: "nomatch tipset min height",
filter: &EventFilter{
minHeight: 14001,
maxHeight: -1,
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch tipset max height",
filter: &EventFilter{
minHeight: -1,
maxHeight: 13999,
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match tipset min height",
filter: &EventFilter{
minHeight: 14000,
maxHeight: -1,
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match tipset cid",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
tipsetCid: cid14000,
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch address",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
addresses: []address.Address{a2},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match address",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
addresses: []address.Address{a1},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match one entry",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "match one entry with alternate values",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("cancel"),
[]byte("propose"),
[]byte("approval"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch one entry by missing value",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("cancel"),
[]byte("propose"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry by missing key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"method": {
[]byte("approval"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "match one entry with multiple keys",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"signer": {
[]byte("addr1"),
},
},
},
te: events14000,
want: oneCollectedEvent,
},
{
name: "nomatch one entry with one mismatching key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"approver": {
[]byte("addr1"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry with one mismatching value",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"type": {
[]byte("approval"),
},
"signer": {
[]byte("addr2"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
{
name: "nomatch one entry with one unindexed key",
filter: &EventFilter{
minHeight: -1,
maxHeight: -1,
keys: map[string][][]byte{
"amount": {
[]byte("2988181"),
},
},
},
te: events14000,
want: noCollectedEvents,
},
}
for _, tc := range testCases {
tc := tc // appease lint
t.Run(tc.name, func(t *testing.T) {
if err := ei.PrefillFilter(context.Background(), tc.filter); err != nil {
require.NoError(t, err, "prefill filter events")
}
coll := tc.filter.TakeCollectedEvents(context.Background())
require.ElementsMatch(t, coll, tc.want)
})
}
}

View File

@ -0,0 +1,143 @@
package filter
import (
"context"
"sync"
"time"
"github.com/ipfs/go-cid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain/types"
)
type MemPoolFilter struct {
id types.FilterID
maxResults int // maximum number of results to collect, 0 is unlimited
ch chan<- interface{}
mu sync.Mutex
collected []cid.Cid
lastTaken time.Time
}
var _ Filter = (*MemPoolFilter)(nil)
func (f *MemPoolFilter) ID() types.FilterID {
return f.id
}
func (f *MemPoolFilter) SetSubChannel(ch chan<- interface{}) {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = ch
f.collected = nil
}
func (f *MemPoolFilter) ClearSubChannel() {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = nil
}
func (f *MemPoolFilter) CollectMessage(ctx context.Context, msg *types.SignedMessage) {
f.mu.Lock()
defer f.mu.Unlock()
// if we have a subscription channel then push message to it
if f.ch != nil {
f.ch <- msg
return
}
if f.maxResults > 0 && len(f.collected) == f.maxResults {
copy(f.collected, f.collected[1:])
f.collected = f.collected[:len(f.collected)-1]
}
f.collected = append(f.collected, msg.Cid())
}
func (f *MemPoolFilter) TakeCollectedMessages(context.Context) []cid.Cid {
f.mu.Lock()
collected := f.collected
f.collected = nil
f.lastTaken = time.Now().UTC()
f.mu.Unlock()
return collected
}
func (f *MemPoolFilter) LastTaken() time.Time {
f.mu.Lock()
defer f.mu.Unlock()
return f.lastTaken
}
type MemPoolFilterManager struct {
MaxFilterResults int
mu sync.Mutex // guards mutations to filters
filters map[types.FilterID]*MemPoolFilter
}
func (m *MemPoolFilterManager) WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate) {
for {
select {
case <-ctx.Done():
return
case u := <-ch:
m.processUpdate(ctx, u)
}
}
}
func (m *MemPoolFilterManager) processUpdate(ctx context.Context, u api.MpoolUpdate) {
// only process added messages
if u.Type == api.MpoolRemove {
return
}
m.mu.Lock()
defer m.mu.Unlock()
if len(m.filters) == 0 {
return
}
// TODO: could run this loop in parallel with errgroup if we expect large numbers of filters
for _, f := range m.filters {
f.CollectMessage(ctx, u.Message)
}
}
func (m *MemPoolFilterManager) Install(ctx context.Context) (*MemPoolFilter, error) {
id, err := newFilterID()
if err != nil {
return nil, xerrors.Errorf("new filter id: %w", err)
}
f := &MemPoolFilter{
id: id,
maxResults: m.MaxFilterResults,
}
m.mu.Lock()
if m.filters == nil {
m.filters = make(map[types.FilterID]*MemPoolFilter)
}
m.filters[id] = f
m.mu.Unlock()
return f, nil
}
func (m *MemPoolFilterManager) Remove(ctx context.Context, id types.FilterID) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, found := m.filters[id]; !found {
return ErrFilterNotFound
}
delete(m.filters, id)
return nil
}

View File

@ -0,0 +1,108 @@
package filter
import (
"context"
"errors"
"sync"
"time"
"github.com/google/uuid"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/types"
)
type Filter interface {
ID() types.FilterID
LastTaken() time.Time
SetSubChannel(chan<- interface{})
ClearSubChannel()
}
type FilterStore interface {
Add(context.Context, Filter) error
Get(context.Context, types.FilterID) (Filter, error)
Remove(context.Context, types.FilterID) error
NotTakenSince(when time.Time) []Filter // returns a list of filters that have not had their collected results taken
}
var (
ErrFilterAlreadyRegistered = errors.New("filter already registered")
ErrFilterNotFound = errors.New("filter not found")
ErrMaximumNumberOfFilters = errors.New("maximum number of filters registered")
)
func newFilterID() (types.FilterID, error) {
rawid, err := uuid.NewRandom()
if err != nil {
return types.FilterID{}, xerrors.Errorf("new uuid: %w", err)
}
id := types.FilterID{}
copy(id[:], rawid[:]) // uuid is 16 bytes, the last 16 bytes are zeroed
return id, nil
}
type memFilterStore struct {
max int
mu sync.Mutex
filters map[types.FilterID]Filter
}
var _ FilterStore = (*memFilterStore)(nil)
func NewMemFilterStore(maxFilters int) FilterStore {
return &memFilterStore{
max: maxFilters,
filters: make(map[types.FilterID]Filter),
}
}
func (m *memFilterStore) Add(_ context.Context, f Filter) error {
m.mu.Lock()
defer m.mu.Unlock()
if len(m.filters) >= m.max {
return ErrMaximumNumberOfFilters
}
if _, exists := m.filters[f.ID()]; exists {
return ErrFilterAlreadyRegistered
}
m.filters[f.ID()] = f
return nil
}
func (m *memFilterStore) Get(_ context.Context, id types.FilterID) (Filter, error) {
m.mu.Lock()
f, found := m.filters[id]
m.mu.Unlock()
if !found {
return nil, ErrFilterNotFound
}
return f, nil
}
func (m *memFilterStore) Remove(_ context.Context, id types.FilterID) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, exists := m.filters[id]; !exists {
return ErrFilterNotFound
}
delete(m.filters, id)
return nil
}
func (m *memFilterStore) NotTakenSince(when time.Time) []Filter {
m.mu.Lock()
defer m.mu.Unlock()
var res []Filter
for _, f := range m.filters {
if f.LastTaken().Before(when) {
res = append(res, f)
}
}
return res
}

View File

@ -0,0 +1,130 @@
package filter
import (
"context"
"sync"
"time"
"golang.org/x/xerrors"
"github.com/filecoin-project/lotus/chain/types"
)
type TipSetFilter struct {
id types.FilterID
maxResults int // maximum number of results to collect, 0 is unlimited
ch chan<- interface{}
mu sync.Mutex
collected []types.TipSetKey
lastTaken time.Time
}
var _ Filter = (*TipSetFilter)(nil)
func (f *TipSetFilter) ID() types.FilterID {
return f.id
}
func (f *TipSetFilter) SetSubChannel(ch chan<- interface{}) {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = ch
f.collected = nil
}
func (f *TipSetFilter) ClearSubChannel() {
f.mu.Lock()
defer f.mu.Unlock()
f.ch = nil
}
func (f *TipSetFilter) CollectTipSet(ctx context.Context, ts *types.TipSet) {
f.mu.Lock()
defer f.mu.Unlock()
// if we have a subscription channel then push tipset to it
if f.ch != nil {
f.ch <- ts
return
}
if f.maxResults > 0 && len(f.collected) == f.maxResults {
copy(f.collected, f.collected[1:])
f.collected = f.collected[:len(f.collected)-1]
}
f.collected = append(f.collected, ts.Key())
}
func (f *TipSetFilter) TakeCollectedTipSets(context.Context) []types.TipSetKey {
f.mu.Lock()
collected := f.collected
f.collected = nil
f.lastTaken = time.Now().UTC()
f.mu.Unlock()
return collected
}
func (f *TipSetFilter) LastTaken() time.Time {
f.mu.Lock()
defer f.mu.Unlock()
return f.lastTaken
}
type TipSetFilterManager struct {
MaxFilterResults int
mu sync.Mutex // guards mutations to filters
filters map[types.FilterID]*TipSetFilter
}
func (m *TipSetFilterManager) Apply(ctx context.Context, from, to *types.TipSet) error {
m.mu.Lock()
defer m.mu.Unlock()
if len(m.filters) == 0 {
return nil
}
// TODO: could run this loop in parallel with errgroup
for _, f := range m.filters {
f.CollectTipSet(ctx, to)
}
return nil
}
func (m *TipSetFilterManager) Revert(ctx context.Context, from, to *types.TipSet) error {
return nil
}
func (m *TipSetFilterManager) Install(ctx context.Context) (*TipSetFilter, error) {
id, err := newFilterID()
if err != nil {
return nil, xerrors.Errorf("new filter id: %w", err)
}
f := &TipSetFilter{
id: id,
maxResults: m.MaxFilterResults,
}
m.mu.Lock()
if m.filters == nil {
m.filters = make(map[types.FilterID]*TipSetFilter)
}
m.filters[id] = f
m.mu.Unlock()
return f, nil
}
func (m *TipSetFilterManager) Remove(ctx context.Context, id types.FilterID) error {
m.mu.Lock()
defer m.mu.Unlock()
if _, found := m.filters[id]; !found {
return ErrFilterNotFound
}
delete(m.filters, id)
return nil
}

View File

@ -469,10 +469,6 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessagesAndNulls(base *types.TipSet,
return nil, xerrors.Errorf("making a block for next tipset failed: %w", err)
}
if err := cg.cs.PersistBlockHeaders(context.TODO(), fblk.Header); err != nil {
return nil, xerrors.Errorf("chainstore AddBlock: %w", err)
}
blks = append(blks, fblk)
}
}

View File

@ -123,12 +123,7 @@ Genesis: {
func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template genesis.Template) (*state.StateTree, map[address.Address]address.Address, error) {
// Create empty state tree
cst := cbor.NewCborStore(bs)
_, err := cst.Put(context.TODO(), []struct{}{})
if err != nil {
return nil, nil, xerrors.Errorf("putting empty object: %w", err)
}
sv, err := state.VersionForNetwork(template.NetworkVersion)
if err != nil {
@ -238,15 +233,12 @@ func MakeInitialStateTree(ctx context.Context, bs bstore.Blockstore, template ge
// Create accounts
for _, info := range template.Accounts {
switch info.Type {
case genesis.TAccount:
if err := CreateAccountActor(ctx, cst, state, info, keyIDs, av); err != nil {
return nil, nil, xerrors.Errorf("failed to create account actor: %w", err)
}
case genesis.TMultisig:
ida, err := address.NewIDAddress(uint64(idStart))
if err != nil {
return nil, nil, err
@ -566,6 +558,11 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
return nil, xerrors.Errorf("make initial state tree failed: %w", err)
}
// Set up the Ethereum Address Manager
if err = SetupEAM(ctx, st, template.NetworkVersion); err != nil {
return nil, xerrors.Errorf("failed to setup EAM: %w", err)
}
stateroot, err := st.Flush(ctx)
if err != nil {
return nil, xerrors.Errorf("flush state tree failed: %w", err)
@ -580,11 +577,27 @@ func MakeGenesisBlock(ctx context.Context, j journal.Journal, bs bstore.Blocksto
return nil, xerrors.Errorf("failed to verify presealed data: %w", err)
}
// setup Storage Miners
stateroot, err = SetupStorageMiners(ctx, cs, sys, stateroot, template.Miners, template.NetworkVersion)
if err != nil {
return nil, xerrors.Errorf("setup miners failed: %w", err)
}
st, err = state.LoadStateTree(st.Store, stateroot)
if err != nil {
return nil, xerrors.Errorf("failed to load updated state tree: %w", err)
}
// Set up Eth null addresses.
if _, err := SetupEthNullAddresses(ctx, st, template.NetworkVersion); err != nil {
return nil, xerrors.Errorf("failed to set up Eth null addresses: %w", err)
}
stateroot, err = st.Flush(ctx)
if err != nil {
return nil, xerrors.Errorf("failed to flush state tree: %w", err)
}
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
emptyroot, err := adt0.MakeEmptyArray(store).Root()
if err != nil {

View File

@ -0,0 +1,139 @@
package genesis
import (
"context"
"fmt"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/actors/adt"
init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/chain/vm"
)
// EthNullAddresses are the Ethereum addresses we want to create zero-balanced EthAccounts in.
// We may want to add null addresses for precompiles going forward.
var EthNullAddresses = []string{
"0x0000000000000000000000000000000000000000",
}
func SetupEAM(_ context.Context, nst *state.StateTree, nv network.Version) error {
av, err := actorstypes.VersionForNetwork(nv)
if err != nil {
return fmt.Errorf("failed to get actors version for network version %d: %w", nv, err)
}
if av < actorstypes.Version10 {
// Not defined before version 10; migration has to create.
return nil
}
codecid, ok := actors.GetActorCodeID(av, manifest.EamKey)
if !ok {
return fmt.Errorf("failed to get CodeCID for EAM during genesis")
}
header := &types.Actor{
Code: codecid,
Head: vm.EmptyObjectCid,
Balance: big.Zero(),
Address: &builtin.EthereumAddressManagerActorAddr, // so that it can create ETH0
}
return nst.SetActor(builtin.EthereumAddressManagerActorAddr, header)
}
// MakeEthNullAddressActor creates a null address actor at the specified Ethereum address.
func MakeEthNullAddressActor(av actorstypes.Version, addr address.Address) (*types.Actor, error) {
actcid, ok := actors.GetActorCodeID(av, manifest.EthAccountKey)
if !ok {
return nil, xerrors.Errorf("failed to get EthAccount actor code ID for actors version %d", av)
}
act := &types.Actor{
Code: actcid,
Head: vm.EmptyObjectCid,
Nonce: 0,
Balance: big.Zero(),
Address: &addr,
}
return act, nil
}
func SetupEthNullAddresses(ctx context.Context, st *state.StateTree, nv network.Version) ([]address.Address, error) {
av, err := actorstypes.VersionForNetwork(nv)
if err != nil {
return nil, xerrors.Errorf("failed to resolve actors version for network version %d: %w", av, err)
}
if av < actorstypes.Version10 {
// Not defined before version 10.
return nil, nil
}
var ethAddresses []ethtypes.EthAddress
for _, addr := range EthNullAddresses {
a, err := ethtypes.ParseEthAddress(addr)
if err != nil {
return nil, xerrors.Errorf("failed to represent the 0x0 as an EthAddress: %w", err)
}
ethAddresses = append(ethAddresses, a)
}
initAct, err := st.GetActor(builtin.InitActorAddr)
if err != nil {
return nil, xerrors.Errorf("failed to load init actor: %w", err)
}
initState, err := init_.Load(adt.WrapStore(ctx, st.Store), initAct)
if err != nil {
return nil, xerrors.Errorf("failed to load init actor state: %w", err)
}
var ret []address.Address
for _, ethAddr := range ethAddresses {
// Place an EthAccount at the 0x0 Eth Null Address.
f4Addr, err := ethAddr.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("failed to compute Filecoin address for Eth addr 0x0: %w", err)
}
idAddr, err := initState.MapAddressToNewID(f4Addr)
if err != nil {
return nil, xerrors.Errorf("failed to map addr in init actor: %w", err)
}
actState, err := MakeEthNullAddressActor(av, f4Addr)
if err != nil {
return nil, xerrors.Errorf("failed to create EthAccount actor for null address: %w", err)
}
if err := st.SetActor(idAddr, actState); err != nil {
return nil, xerrors.Errorf("failed to set Eth Null Address EthAccount actor state: %w", err)
}
ret = append(ret, idAddr)
}
initAct.Head, err = st.Store.Put(ctx, initState)
if err != nil {
return nil, xerrors.Errorf("failed to add init actor state to store: %w", err)
}
if err := st.SetActor(builtin.InitActorAddr, initAct); err != nil {
return nil, xerrors.Errorf("failed to set updated state for init actor: %w", err)
}
return ret, nil
}

View File

@ -33,12 +33,12 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/journal"
"github.com/filecoin-project/lotus/lib/sigs"
"github.com/filecoin-project/lotus/metrics"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
@ -282,7 +282,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted
}
ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.RequiredFunds().Int)
//ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.Value.Int)
// ms.requiredFunds.Sub(ms.requiredFunds, exms.Message.Value.Int)
}
if !has && strict && len(ms.msgs) >= maxActorPendingMessages {
@ -298,7 +298,7 @@ func (ms *msgSet) add(m *types.SignedMessage, mp *MessagePool, strict, untrusted
ms.nextNonce = nextNonce
ms.msgs[m.Message.Nonce] = m
ms.requiredFunds.Add(ms.requiredFunds, m.Message.RequiredFunds().Int)
//ms.requiredFunds.Add(ms.requiredFunds, m.Message.Value.Int)
// ms.requiredFunds.Add(ms.requiredFunds, m.Message.Value.Int)
return !has, nil
}
@ -318,7 +318,7 @@ func (ms *msgSet) rm(nonce uint64, applied bool) {
}
ms.requiredFunds.Sub(ms.requiredFunds, m.Message.RequiredFunds().Int)
//ms.requiredFunds.Sub(ms.requiredFunds, m.Message.Value.Int)
// ms.requiredFunds.Sub(ms.requiredFunds, m.Message.Value.Int)
delete(ms.msgs, nonce)
// adjust next nonce
@ -344,7 +344,7 @@ func (ms *msgSet) getRequiredFunds(nonce uint64) types.BigInt {
m, has := ms.msgs[nonce]
if has {
requiredFunds.Sub(requiredFunds, m.Message.RequiredFunds().Int)
//requiredFunds.Sub(requiredFunds, m.Message.Value.Int)
// requiredFunds.Sub(requiredFunds, m.Message.Value.Int)
}
return types.BigInt{Int: requiredFunds}
@ -476,7 +476,7 @@ func (mp *MessagePool) resolveToKey(ctx context.Context, addr address.Address) (
}
// resolve the address
ka, err := mp.api.StateAccountKeyAtFinality(ctx, addr, mp.curTs)
ka, err := mp.api.StateDeterministicAddressAtFinality(ctx, addr, mp.curTs)
if err != nil {
return address.Undef, err
}
@ -772,11 +772,9 @@ func sigCacheKey(m *types.SignedMessage) (string, error) {
if len(m.Signature.Data) != ffi.SignatureBytes {
return "", fmt.Errorf("bls signature incorrectly sized")
}
hashCache := blake2b.Sum256(append(m.Cid().Bytes(), m.Signature.Data...))
return string(hashCache[:]), nil
case crypto.SigTypeSecp256k1:
case crypto.SigTypeSecp256k1, crypto.SigTypeDelegated:
return string(m.Cid().Bytes()), nil
default:
return "", xerrors.Errorf("unrecognized signature type: %d", m.Signature.Type)
@ -795,8 +793,8 @@ func (mp *MessagePool) VerifyMsgSig(m *types.SignedMessage) error {
return nil
}
if err := sigs.Verify(&m.Signature, m.Message.From, m.Message.Cid().Bytes()); err != nil {
return err
if err := consensus.AuthenticateMessage(m, m.Message.From); err != nil {
return xerrors.Errorf("failed to validate signature: %w", err)
}
mp.sigValCache.Add(sck, struct{}{})
@ -816,7 +814,7 @@ func (mp *MessagePool) checkBalance(ctx context.Context, m *types.SignedMessage,
}
// add Value for soft failure check
//requiredFunds = types.BigAdd(requiredFunds, m.Message.Value)
// requiredFunds = types.BigAdd(requiredFunds, m.Message.Value)
mset, ok, err := mp.getPendingMset(ctx, m.Message.From)
if err != nil {
@ -853,18 +851,32 @@ func (mp *MessagePool) addTs(ctx context.Context, m *types.SignedMessage, curTs
mp.lk.Lock()
defer mp.lk.Unlock()
senderAct, err := mp.api.GetActorAfter(m.Message.From, curTs)
if err != nil {
return false, xerrors.Errorf("failed to get sender actor: %w", err)
}
// This message can only be included in the _next_ epoch and beyond, hence the +1.
epoch := curTs.Height() + 1
nv := mp.api.StateNetworkVersion(ctx, epoch)
// TODO: I'm not thrilled about depending on filcns here, but I prefer this to duplicating logic
if !consensus.IsValidForSending(nv, senderAct) {
return false, xerrors.Errorf("sender actor %s is not a valid top-level sender", m.Message.From)
}
publish, err := mp.verifyMsgBeforeAdd(ctx, m, curTs, local)
if err != nil {
return false, err
return false, xerrors.Errorf("verify msg failed: %w", err)
}
if err := mp.checkBalance(ctx, m, curTs); err != nil {
return false, err
return false, xerrors.Errorf("failed to check balance: %w", err)
}
err = mp.addLocked(ctx, m, !local, untrusted)
if err != nil {
return false, err
return false, xerrors.Errorf("failed to add locked: %w", err)
}
if local {

View File

@ -155,14 +155,14 @@ func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) (
}
return &types.Actor{
Code: builtin2.StorageMarketActorCodeID,
Code: builtin2.AccountActorCodeID,
Nonce: nonce,
Balance: balance,
}, nil
}
func (tma *testMpoolAPI) StateAccountKeyAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 {
func (tma *testMpoolAPI) StateDeterministicAddressAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 && addr.Protocol() != address.Delegated {
return address.Undef, fmt.Errorf("given address was not a key addr")
}
return addr, nil
@ -214,7 +214,7 @@ func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipS
func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) {
t.Helper()
//stm: @CHAIN_MEMPOOL_GET_NONCE_001
// stm: @CHAIN_MEMPOOL_GET_NONCE_001
n, err := mp.GetNonce(context.TODO(), addr, types.EmptyTSK)
if err != nil {
t.Fatal(err)
@ -233,7 +233,7 @@ func mustAdd(t *testing.T, mp *MessagePool, msg *types.SignedMessage) {
}
func TestMessagePool(t *testing.T) {
//stm: @CHAIN_MEMPOOL_GET_NONCE_001
// stm: @CHAIN_MEMPOOL_GET_NONCE_001
tma := newTestMpoolAPI()
@ -336,7 +336,7 @@ func TestCheckMessageBig(t *testing.T) {
Message: *msg,
Signature: *sig,
}
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
err = mp.Add(context.TODO(), sm)
assert.ErrorIs(t, err, ErrMessageTooBig)
}
@ -378,10 +378,10 @@ func TestMessagePoolMessagesInEachBlock(t *testing.T) {
tma.applyBlock(t, a)
tsa := mock.TipSet(a)
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
_, _ = mp.Pending(context.TODO())
//stm: @CHAIN_MEMPOOL_SELECT_001
// stm: @CHAIN_MEMPOOL_SELECT_001
selm, _ := mp.SelectMessages(context.Background(), tsa, 1)
if len(selm) == 0 {
t.Fatal("should have returned the rest of the messages")
@ -442,7 +442,7 @@ func TestRevertMessages(t *testing.T) {
assertNonce(t, mp, sender, 4)
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
p, _ := mp.Pending(context.TODO())
fmt.Printf("%+v\n", p)
if len(p) != 3 {
@ -501,7 +501,7 @@ func TestPruningSimple(t *testing.T) {
mp.Prune()
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
msgs, _ := mp.Pending(context.TODO())
if len(msgs) != 5 {
t.Fatal("expected only 5 messages in pool, got: ", len(msgs))
@ -544,7 +544,7 @@ func TestLoadLocal(t *testing.T) {
msgs := make(map[cid.Cid]struct{})
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
cid, err := mp.Push(context.TODO(), m, true)
if err != nil {
t.Fatal(err)
@ -561,7 +561,7 @@ func TestLoadLocal(t *testing.T) {
t.Fatal(err)
}
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
pmsgs, _ := mp.Pending(context.TODO())
if len(msgs) != len(pmsgs) {
t.Fatalf("expected %d messages, but got %d", len(msgs), len(pmsgs))
@ -617,7 +617,7 @@ func TestClearAll(t *testing.T) {
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m, true)
if err != nil {
t.Fatal(err)
@ -629,10 +629,10 @@ func TestClearAll(t *testing.T) {
mustAdd(t, mp, m)
}
//stm: @CHAIN_MEMPOOL_CLEAR_001
// stm: @CHAIN_MEMPOOL_CLEAR_001
mp.Clear(context.Background(), true)
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
pending, _ := mp.Pending(context.TODO())
if len(pending) > 0 {
t.Fatalf("cleared the mpool, but got %d pending messages", len(pending))
@ -675,7 +675,7 @@ func TestClearNonLocal(t *testing.T) {
gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}]
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m, true)
if err != nil {
t.Fatal(err)
@ -687,10 +687,10 @@ func TestClearNonLocal(t *testing.T) {
mustAdd(t, mp, m)
}
//stm: @CHAIN_MEMPOOL_CLEAR_001
// stm: @CHAIN_MEMPOOL_CLEAR_001
mp.Clear(context.Background(), false)
//stm: @CHAIN_MEMPOOL_PENDING_001
// stm: @CHAIN_MEMPOOL_PENDING_001
pending, _ := mp.Pending(context.TODO())
if len(pending) != 10 {
t.Fatalf("expected 10 pending messages, but got %d instead", len(pending))
@ -748,7 +748,7 @@ func TestUpdates(t *testing.T) {
for i := 0; i < 10; i++ {
m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1))
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
_, err := mp.Push(context.TODO(), m, true)
if err != nil {
t.Fatal(err)
@ -772,7 +772,7 @@ func TestUpdates(t *testing.T) {
}
func TestMessageBelowMinGasFee(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -818,7 +818,7 @@ func TestMessageBelowMinGasFee(t *testing.T) {
}
func TestMessageValueTooHigh(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -866,7 +866,7 @@ func TestMessageValueTooHigh(t *testing.T) {
}
func TestMessageSignatureInvalid(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -911,7 +911,7 @@ func TestMessageSignatureInvalid(t *testing.T) {
}
func TestAddMessageTwice(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -957,7 +957,7 @@ func TestAddMessageTwice(t *testing.T) {
}
func TestAddMessageTwiceNonceGap(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -1011,7 +1011,7 @@ func TestAddMessageTwiceCidDiff(t *testing.T) {
// Create message with different data, so CID is different
sm2 := makeTestMessage(w, from, to, 0, 50_000_001, minimumBaseFee.Uint64())
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
// then try to add message again
err = mp.Add(context.TODO(), sm2)
// assert.Contains(t, err.Error(), "replace by fee has too low GasPremium")
@ -1020,7 +1020,7 @@ func TestAddMessageTwiceCidDiff(t *testing.T) {
}
func TestAddMessageTwiceCidDiffReplaced(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -1049,7 +1049,7 @@ func TestAddMessageTwiceCidDiffReplaced(t *testing.T) {
}
func TestRemoveMessage(t *testing.T) {
//stm: @CHAIN_MEMPOOL_PUSH_001
// stm: @CHAIN_MEMPOOL_PUSH_001
tma := newTestMpoolAPI()
w, err := wallet.NewWallet(wallet.NewMemKeyStore())
@ -1071,11 +1071,11 @@ func TestRemoveMessage(t *testing.T) {
sm := makeTestMessage(w, from, to, 0, 50_000_000, minimumBaseFee.Uint64())
mustAdd(t, mp, sm)
//stm: @CHAIN_MEMPOOL_REMOVE_001
// stm: @CHAIN_MEMPOOL_REMOVE_001
// remove message for sender
mp.Remove(context.TODO(), from, sm.Message.Nonce, true)
//stm: @CHAIN_MEMPOOL_PENDING_FOR_001
// stm: @CHAIN_MEMPOOL_PENDING_FOR_001
// check messages in pool: should be none present
msgs := mp.pendingFor(context.TODO(), from)
assert.Len(t, msgs, 0)

View File

@ -28,7 +28,7 @@ type Provider interface {
PutMessage(ctx context.Context, m types.ChainMsg) (cid.Cid, error)
PubSubPublish(string, []byte) error
GetActorAfter(address.Address, *types.TipSet) (*types.Actor, error)
StateAccountKeyAtFinality(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateDeterministicAddressAtFinality(context.Context, address.Address, *types.TipSet) (address.Address, error)
StateNetworkVersion(context.Context, abi.ChainEpoch) network.Version
MessagesForBlock(context.Context, *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error)
MessagesForTipset(context.Context, *types.TipSet) ([]types.ChainMsg, error)
@ -74,7 +74,7 @@ func (mpp *mpoolProvider) PutMessage(ctx context.Context, m types.ChainMsg) (cid
}
func (mpp *mpoolProvider) PubSubPublish(k string, v []byte) error {
return mpp.ps.Publish(k, v) //nolint
return mpp.ps.Publish(k, v) // nolint
}
func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) {
@ -102,8 +102,8 @@ func (mpp *mpoolProvider) GetActorAfter(addr address.Address, ts *types.TipSet)
return st.GetActor(addr)
}
func (mpp *mpoolProvider) StateAccountKeyAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return mpp.sm.ResolveToKeyAddressAtFinality(ctx, addr, ts)
func (mpp *mpoolProvider) StateDeterministicAddressAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return mpp.sm.ResolveToDeterministicAddressAtFinality(ctx, addr, ts)
}
func (mpp *mpoolProvider) StateNetworkVersion(ctx context.Context, height abi.ChainEpoch) network.Version {

View File

@ -97,7 +97,7 @@ func (sm *selectedMessages) tryToAdd(mc *msgChain) bool {
sm.msgs = append(sm.msgs, mc.msgs...)
sm.blsLimit -= l
sm.gasLimit -= mc.gasLimit
} else if mc.sigType == crypto.SigTypeSecp256k1 {
} else if mc.sigType == crypto.SigTypeSecp256k1 || mc.sigType == crypto.SigTypeDelegated {
if sm.secpLimit < l {
return false
}
@ -123,7 +123,7 @@ func (sm *selectedMessages) tryToAddWithDeps(mc *msgChain, mp *MessagePool, base
if mc.sigType == crypto.SigTypeBLS {
smMsgLimit = sm.blsLimit
} else if mc.sigType == crypto.SigTypeSecp256k1 {
} else if mc.sigType == crypto.SigTypeSecp256k1 || mc.sigType == crypto.SigTypeDelegated {
smMsgLimit = sm.secpLimit
} else {
return false
@ -174,7 +174,7 @@ func (sm *selectedMessages) tryToAddWithDeps(mc *msgChain, mp *MessagePool, base
if mc.sigType == crypto.SigTypeBLS {
sm.blsLimit -= chainMsgLimit
} else if mc.sigType == crypto.SigTypeSecp256k1 {
} else if mc.sigType == crypto.SigTypeSecp256k1 || mc.sigType == crypto.SigTypeDelegated {
sm.secpLimit -= chainMsgLimit
}
@ -187,7 +187,7 @@ func (sm *selectedMessages) trimChain(mc *msgChain, mp *MessagePool, baseFee typ
if msgLimit > sm.blsLimit {
msgLimit = sm.blsLimit
}
} else if mc.sigType == crypto.SigTypeSecp256k1 {
} else if mc.sigType == crypto.SigTypeSecp256k1 || mc.sigType == crypto.SigTypeDelegated {
if msgLimit > sm.secpLimit {
msgLimit = sm.secpLimit
}

View File

@ -31,6 +31,7 @@ import (
"github.com/filecoin-project/lotus/chain/types/mock"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
)

View File

@ -48,7 +48,7 @@ func GetMinerWorkerRaw(ctx context.Context, sm *StateManager, st cid.Cid, maddr
return address.Undef, xerrors.Errorf("failed to load actor info: %w", err)
}
return vm.ResolveToKeyAddr(state, sm.cs.ActorStore(ctx), info.Worker)
return vm.ResolveToDeterministicAddr(state, sm.cs.ActorStore(ctx), info.Worker)
}
func GetPower(ctx context.Context, sm *StateManager, ts *types.TipSet, maddr address.Address) (power.Claim, power.Claim, bool, error) {
@ -381,7 +381,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
return nil, err
}
worker, err := sm.ResolveToKeyAddress(ctx, info.Worker, ts)
worker, err := sm.ResolveToDeterministicAddress(ctx, info.Worker, ts)
if err != nil {
return nil, xerrors.Errorf("resolving worker address: %w", err)
}

View File

@ -143,6 +143,7 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr
vmopt := &vm.VMOpts{
StateBase: stateCid,
Epoch: vmHeight,
Timestamp: ts.MinTimestamp(),
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, nvGetter),
Bstore: buffStore,
Actors: sm.tsExec.NewActorRegistry(),
@ -199,7 +200,7 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr
var ret *vm.ApplyRet
var gasInfo api.MsgGasCost
if checkGas {
fromKey, err := sm.ResolveToKeyAddress(ctx, msg.From, ts)
fromKey, err := sm.ResolveToDeterministicAddress(ctx, msg.From, ts)
if err != nil {
return nil, xerrors.Errorf("could not resolve key: %w", err)
}
@ -217,6 +218,14 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr
Data: make([]byte, 65),
},
}
case address.Delegated:
msgApply = &types.SignedMessage{
Message: *msg,
Signature: crypto.Signature{
Type: crypto.SigTypeDelegated,
Data: make([]byte, 65),
},
}
}
ret, err = vmi.ApplyMessage(ctx, msgApply)

View File

@ -48,7 +48,7 @@ func (s *RPCStateManager) LookupID(ctx context.Context, addr address.Address, ts
return s.gapi.StateLookupID(ctx, addr, ts.Key())
}
func (s *RPCStateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
func (s *RPCStateManager) ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
return s.gapi.StateAccountKey(ctx, addr, ts.Key())
}

View File

@ -42,7 +42,7 @@ type StateManagerAPI interface {
GetPaychState(ctx context.Context, addr address.Address, ts *types.TipSet) (*types.Actor, paych.State, error)
LoadActorTsk(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*types.Actor, error)
LookupID(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error)
}
type versionSpec struct {
@ -207,11 +207,11 @@ func (sm *StateManager) Beacon() beacon.Schedule {
return sm.beacon
}
// ResolveToKeyAddress is similar to `vm.ResolveToKeyAddr` but does not allow `Actor` type of addresses.
// ResolveToDeterministicAddress is similar to `vm.ResolveToDeterministicAddr` but does not allow `Actor` type of addresses.
// Uses the `TipSet` `ts` to generate the VM state.
func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
func (sm *StateManager) ResolveToDeterministicAddress(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
switch addr.Protocol() {
case address.BLS, address.SECP256K1:
case address.BLS, address.SECP256K1, address.Delegated:
return addr, nil
case address.Actor:
return address.Undef, xerrors.New("cannot resolve actor address to key address")
@ -230,7 +230,7 @@ func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Ad
return address.Undef, xerrors.Errorf("failed to load parent state tree at tipset %s: %w", ts.Parents(), err)
}
resolved, err := vm.ResolveToKeyAddr(tree, cst, addr)
resolved, err := vm.ResolveToDeterministicAddr(tree, cst, addr)
if err == nil {
return resolved, nil
}
@ -246,14 +246,14 @@ func (sm *StateManager) ResolveToKeyAddress(ctx context.Context, addr address.Ad
return address.Undef, xerrors.Errorf("failed to load state tree at tipset %s: %w", ts, err)
}
return vm.ResolveToKeyAddr(tree, cst, addr)
return vm.ResolveToDeterministicAddr(tree, cst, addr)
}
// ResolveToKeyAddressAtFinality is similar to stmgr.ResolveToKeyAddress but fails if the ID address being resolved isn't reorg-stable yet.
// ResolveToDeterministicAddressAtFinality is similar to stmgr.ResolveToDeterministicAddress but fails if the ID address being resolved isn't reorg-stable yet.
// It should not be used for consensus-critical subsystems.
func (sm *StateManager) ResolveToKeyAddressAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
func (sm *StateManager) ResolveToDeterministicAddressAtFinality(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) {
switch addr.Protocol() {
case address.BLS, address.SECP256K1:
case address.BLS, address.SECP256K1, address.Delegated:
return addr, nil
case address.Actor:
return address.Undef, xerrors.New("cannot resolve actor address to key address")
@ -287,7 +287,7 @@ func (sm *StateManager) ResolveToKeyAddressAtFinality(ctx context.Context, addr
}
}
resolved, err := vm.ResolveToKeyAddr(tree, cst, addr)
resolved, err := vm.ResolveToDeterministicAddr(tree, cst, addr)
if err == nil {
return resolved, nil
}
@ -296,7 +296,7 @@ func (sm *StateManager) ResolveToKeyAddressAtFinality(ctx context.Context, addr
}
func (sm *StateManager) GetBlsPublicKey(ctx context.Context, addr address.Address, ts *types.TipSet) (pubk []byte, err error) {
kaddr, err := sm.ResolveToKeyAddress(ctx, addr, ts)
kaddr, err := sm.ResolveToDeterministicAddress(ctx, addr, ts)
if err != nil {
return pubk, xerrors.Errorf("failed to resolve address to key address: %w", err)
}

View File

@ -2,6 +2,7 @@ package stmgr
import (
"context"
"errors"
"fmt"
"reflect"
@ -27,6 +28,8 @@ import (
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
var ErrMetadataNotFound = errors.New("actor metadata not found")
func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, method abi.MethodNum, ts *types.TipSet) (cbg.CBORUnmarshaler, error) {
act, err := sm.LoadActor(ctx, to, ts)
if err != nil {
@ -35,7 +38,7 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
m, found := sm.tsExec.NewActorRegistry().Methods[act.Code][method]
if !found {
return nil, fmt.Errorf("unknown method %d for actor %s", method, act.Code)
return nil, fmt.Errorf("unknown method %d for actor %s: %w", method, act.Code, ErrMetadataNotFound)
}
return reflect.New(m.Ret.Elem()).Interface().(cbg.CBORUnmarshaler), nil
@ -44,7 +47,7 @@ func GetReturnType(ctx context.Context, sm *StateManager, to address.Address, me
func GetParamType(ar *vm.ActorRegistry, actCode cid.Cid, method abi.MethodNum) (cbg.CBORUnmarshaler, error) {
m, found := ar.Methods[actCode][method]
if !found {
return nil, fmt.Errorf("unknown method %d for actor %s", method, actCode)
return nil, fmt.Errorf("unknown method %d for actor %s: %w", method, actCode, ErrMetadataNotFound)
}
return reflect.New(m.Params.Elem()).Interface().(cbg.CBORUnmarshaler), nil
}
@ -87,6 +90,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch,
vmopt := &vm.VMOpts{
StateBase: base,
Epoch: height,
Timestamp: ts.MinTimestamp(),
Rand: r,
Bstore: sm.cs.StateBlockstore(),
Actors: sm.tsExec.NewActorRegistry(),

View File

@ -1,6 +1,7 @@
package store
import (
"bytes"
"context"
"encoding/json"
"errors"
@ -375,10 +376,8 @@ func (cs *ChainStore) SetGenesis(ctx context.Context, b *types.BlockHeader) erro
}
func (cs *ChainStore) PutTipSet(ctx context.Context, ts *types.TipSet) error {
for _, b := range ts.Blocks() {
if err := cs.PersistBlockHeaders(ctx, b); err != nil {
return err
}
if err := cs.PersistTipset(ctx, ts); err != nil {
return xerrors.Errorf("failed to persist tipset: %w", err)
}
expanded, err := cs.expandTipset(ctx, ts.Blocks()[0])
@ -646,7 +645,7 @@ func (cs *ChainStore) takeHeaviestTipSet(ctx context.Context, ts *types.TipSet)
if err := cs.writeHead(ctx, ts); err != nil {
log.Errorf("failed to write chain head: %s", err)
return nil
return err
}
return nil
@ -958,7 +957,24 @@ func (cs *ChainStore) AddToTipSetTracker(ctx context.Context, b *types.BlockHead
return nil
}
func (cs *ChainStore) PersistBlockHeaders(ctx context.Context, b ...*types.BlockHeader) error {
func (cs *ChainStore) PersistTipset(ctx context.Context, ts *types.TipSet) error {
if err := cs.persistBlockHeaders(ctx, ts.Blocks()...); err != nil {
return xerrors.Errorf("failed to persist block headers: %w", err)
}
tsBlk, err := ts.Key().ToStorageBlock()
if err != nil {
return xerrors.Errorf("failed to get tipset key block: %w", err)
}
if err = cs.chainLocalBlockstore.Put(ctx, tsBlk); err != nil {
return xerrors.Errorf("failed to put tipset key block: %w", err)
}
return nil
}
func (cs *ChainStore) persistBlockHeaders(ctx context.Context, b ...*types.BlockHeader) error {
sbs := make([]block.Block, len(b))
for i, header := range b {
@ -1026,23 +1042,6 @@ func (cs *ChainStore) expandTipset(ctx context.Context, b *types.BlockHeader) (*
return types.NewTipSet(all)
}
func (cs *ChainStore) AddBlock(ctx context.Context, b *types.BlockHeader) error {
if err := cs.PersistBlockHeaders(ctx, b); err != nil {
return err
}
ts, err := cs.expandTipset(ctx, b)
if err != nil {
return err
}
if err := cs.MaybeTakeHeavierTipSet(ctx, ts); err != nil {
return xerrors.Errorf("MaybeTakeHeavierTipSet failed: %w", err)
}
return nil
}
func (cs *ChainStore) GetGenesis(ctx context.Context) (*types.BlockHeader, error) {
data, err := cs.metadataDs.Get(ctx, dstore.NewKey("0"))
if err != nil {
@ -1165,6 +1164,24 @@ func (cs *ChainStore) GetTipsetByHeight(ctx context.Context, h abi.ChainEpoch, t
return cs.LoadTipSet(ctx, lbts.Parents())
}
func (cs *ChainStore) GetTipSetByCid(ctx context.Context, c cid.Cid) (*types.TipSet, error) {
blk, err := cs.chainBlockstore.Get(ctx, c)
if err != nil {
return nil, xerrors.Errorf("cannot find tipset with cid %s: %w", c, err)
}
tsk := new(types.TipSetKey)
if err := tsk.UnmarshalCBOR(bytes.NewReader(blk.RawData())); err != nil {
return nil, xerrors.Errorf("cannot unmarshal block into tipset key: %w", err)
}
ts, err := cs.GetTipSetFromKey(ctx, *tsk)
if err != nil {
return nil, xerrors.Errorf("cannot get tipset from key: %w", err)
}
return ts, nil
}
func (cs *ChainStore) Weight(ctx context.Context, hts *types.TipSet) (types.BigInt, error) { // todo remove
return cs.weight(ctx, cs.StateBlockstore(), hts)
}

View File

@ -228,7 +228,7 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) bool {
// TODO: IMPORTANT(GARBAGE) this needs to be put in the 'temporary' side of
// the blockstore
if err := syncer.store.PersistBlockHeaders(ctx, fts.TipSet().Blocks()...); err != nil {
if err := syncer.store.PersistTipset(ctx, fts.TipSet()); err != nil {
log.Warn("failed to persist incoming block header: ", err)
return false
}
@ -1145,7 +1145,7 @@ func persistMessages(ctx context.Context, bs bstore.Blockstore, bst *exchange.Co
}
}
for _, m := range bst.Secpk {
if m.Signature.Type != crypto.SigTypeSecp256k1 {
if m.Signature.Type != crypto.SigTypeSecp256k1 && m.Signature.Type != crypto.SigTypeDelegated {
return xerrors.Errorf("unknown signature type on message %s: %q", m.Cid(), m.Signature.Type)
}
//log.Infof("putting secp256k1 message: %s", m.Cid())
@ -1198,16 +1198,13 @@ func (syncer *Syncer) collectChain(ctx context.Context, ts *types.TipSet, hts *t
ss.SetStage(api.StagePersistHeaders)
toPersist := make([]*types.BlockHeader, 0, len(headers)*int(build.BlocksPerEpoch))
for _, ts := range headers {
toPersist = append(toPersist, ts.Blocks()...)
if err := syncer.store.PersistTipset(ctx, ts); err != nil {
err = xerrors.Errorf("failed to persist synced tipset to the chainstore: %w", err)
ss.Error(err)
return err
}
}
if err := syncer.store.PersistBlockHeaders(ctx, toPersist...); err != nil {
err = xerrors.Errorf("failed to persist synced blocks to the chainstore: %w", err)
ss.Error(err)
return err
}
toPersist = nil
ss.SetStage(api.StageMessages)

View File

@ -306,13 +306,13 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
require.NoError(tu.t, err)
tu.t.Cleanup(func() { _ = stop(context.Background()) })
lastTs := blocks[len(blocks)-1].Blocks
for _, lastB := range lastTs {
cs := out.(*impl.FullNodeAPI).ChainAPI.Chain
lastTs := blocks[len(blocks)-1]
cs := out.(*impl.FullNodeAPI).ChainAPI.Chain
for _, lastB := range lastTs.Blocks {
require.NoError(tu.t, cs.AddToTipSetTracker(context.Background(), lastB.Header))
err = cs.AddBlock(tu.ctx, lastB.Header)
require.NoError(tu.t, err)
}
err = cs.PutTipSet(tu.ctx, lastTs.TipSet())
require.NoError(tu.t, err)
tu.genesis = genesis
tu.blocks = blocks

View File

@ -26,7 +26,7 @@ type ActorV5 struct {
Head cid.Cid
Nonce uint64
Balance BigInt
// Predictable Address
// Deterministic Address.
Address *address.Address
}

View File

@ -15,7 +15,6 @@ import (
address "github.com/filecoin-project/go-address"
abi "github.com/filecoin-project/go-state-types/abi"
crypto "github.com/filecoin-project/go-state-types/crypto"
exitcode "github.com/filecoin-project/go-state-types/exitcode"
proof "github.com/filecoin-project/go-state-types/proof"
)
@ -1289,154 +1288,6 @@ func (t *ActorV5) UnmarshalCBOR(r io.Reader) (err error) {
return nil
}
var lengthBufMessageReceipt = []byte{131}
func (t *MessageReceipt) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
if _, err := cw.Write(lengthBufMessageReceipt); err != nil {
return err
}
// t.ExitCode (exitcode.ExitCode) (int64)
if t.ExitCode >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
return err
}
}
// t.Return ([]uint8) (slice)
if len(t.Return) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Return was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
return err
}
if _, err := cw.Write(t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
if t.GasUsed >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
return err
}
}
return nil
}
func (t *MessageReceipt) UnmarshalCBOR(r io.Reader) (err error) {
*t = MessageReceipt{}
cr := cbg.NewCborReader(r)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
defer func() {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
}()
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.ExitCode (exitcode.ExitCode) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.ExitCode = exitcode.ExitCode(extraI)
}
// t.Return ([]uint8) (slice)
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if extra > cbg.ByteArrayMaxLen {
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
if extra > 0 {
t.Return = make([]uint8, extra)
}
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.GasUsed = int64(extraI)
}
return nil
}
var lengthBufBlockMsg = []byte{131}
func (t *BlockMsg) MarshalCBOR(w io.Writer) error {
@ -1986,3 +1837,224 @@ func (t *StateInfo0) UnmarshalCBOR(r io.Reader) (err error) {
return nil
}
var lengthBufEvent = []byte{130}
func (t *Event) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
if _, err := cw.Write(lengthBufEvent); err != nil {
return err
}
// t.Emitter (abi.ActorID) (uint64)
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Emitter)); err != nil {
return err
}
// t.Entries ([]types.EventEntry) (slice)
if len(t.Entries) > cbg.MaxLength {
return xerrors.Errorf("Slice value in field t.Entries was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Entries))); err != nil {
return err
}
for _, v := range t.Entries {
if err := v.MarshalCBOR(cw); err != nil {
return err
}
}
return nil
}
func (t *Event) UnmarshalCBOR(r io.Reader) (err error) {
*t = Event{}
cr := cbg.NewCborReader(r)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
defer func() {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
}()
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 2 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.Emitter (abi.ActorID) (uint64)
{
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint64 field")
}
t.Emitter = abi.ActorID(extra)
}
// t.Entries ([]types.EventEntry) (slice)
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if extra > cbg.MaxLength {
return fmt.Errorf("t.Entries: array too large (%d)", extra)
}
if maj != cbg.MajArray {
return fmt.Errorf("expected cbor array")
}
if extra > 0 {
t.Entries = make([]EventEntry, extra)
}
for i := 0; i < int(extra); i++ {
var v EventEntry
if err := v.UnmarshalCBOR(cr); err != nil {
return err
}
t.Entries[i] = v
}
return nil
}
var lengthBufEventEntry = []byte{131}
func (t *EventEntry) MarshalCBOR(w io.Writer) error {
if t == nil {
_, err := w.Write(cbg.CborNull)
return err
}
cw := cbg.NewCborWriter(w)
if _, err := cw.Write(lengthBufEventEntry); err != nil {
return err
}
// t.Flags (uint8) (uint8)
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Flags)); err != nil {
return err
}
// t.Key (string) (string)
if len(t.Key) > cbg.MaxLength {
return xerrors.Errorf("Value in field t.Key was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil {
return err
}
if _, err := io.WriteString(w, string(t.Key)); err != nil {
return err
}
// t.Value ([]uint8) (slice)
if len(t.Value) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Value was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Value))); err != nil {
return err
}
if _, err := cw.Write(t.Value[:]); err != nil {
return err
}
return nil
}
func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) {
*t = EventEntry{}
cr := cbg.NewCborReader(r)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
defer func() {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
}()
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
if extra != 3 {
return fmt.Errorf("cbor input had wrong number of fields")
}
// t.Flags (uint8) (uint8)
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if maj != cbg.MajUnsignedInt {
return fmt.Errorf("wrong type for uint8 field")
}
if extra > math.MaxUint8 {
return fmt.Errorf("integer in input was too large for uint8 field")
}
t.Flags = uint8(extra)
// t.Key (string) (string)
{
sval, err := cbg.ReadString(cr)
if err != nil {
return err
}
t.Key = string(sval)
}
// t.Value ([]uint8) (slice)
maj, extra, err = cr.ReadHeader()
if err != nil {
return err
}
if extra > cbg.ByteArrayMaxLen {
return fmt.Errorf("t.Value: byte array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
if extra > 0 {
t.Value = make([]uint8, extra)
}
if _, err := io.ReadFull(cr, t.Value[:]); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,618 @@
package ethtypes
import (
"bytes"
"encoding/binary"
"fmt"
mathbig "math/big"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/crypto/sha3"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
gocrypto "github.com/filecoin-project/go-crypto"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
typescrypto "github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
)
const Eip1559TxType = 2
type EthTx struct {
ChainID EthUint64 `json:"chainId"`
Nonce EthUint64 `json:"nonce"`
Hash EthHash `json:"hash"`
BlockHash *EthHash `json:"blockHash"`
BlockNumber *EthUint64 `json:"blockNumber"`
TransactionIndex *EthUint64 `json:"transactionIndex"`
From EthAddress `json:"from"`
To *EthAddress `json:"to"`
Value EthBigInt `json:"value"`
Type EthUint64 `json:"type"`
Input EthBytes `json:"input"`
Gas EthUint64 `json:"gas"`
MaxFeePerGas EthBigInt `json:"maxFeePerGas"`
MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"`
V EthBigInt `json:"v"`
R EthBigInt `json:"r"`
S EthBigInt `json:"s"`
}
type EthTxArgs struct {
ChainID int `json:"chainId"`
Nonce int `json:"nonce"`
To *EthAddress `json:"to"`
Value big.Int `json:"value"`
MaxFeePerGas big.Int `json:"maxFeePerGas"`
MaxPriorityFeePerGas big.Int `json:"maxPriorityFeePerGas"`
GasLimit int `json:"gasLimit"`
Input []byte `json:"input"`
V big.Int `json:"v"`
R big.Int `json:"r"`
S big.Int `json:"s"`
}
func EthTxArgsFromMessage(msg *types.Message) (EthTxArgs, error) {
var (
to *EthAddress
params []byte
paramsReader = bytes.NewReader(msg.Params)
)
if msg.Version != 0 {
return EthTxArgs{}, xerrors.Errorf("unsupported msg version: %d", msg.Version)
}
if msg.To == builtintypes.EthereumAddressManagerActorAddr {
switch msg.Method {
case builtintypes.MethodsEAM.CreateExternal:
var create abi.CborBytes
if err := create.UnmarshalCBOR(paramsReader); err != nil {
return EthTxArgs{}, err
}
params = create
default:
return EthTxArgs{}, fmt.Errorf("unsupported EAM method")
}
} else {
addr, err := EthAddressFromFilecoinAddress(msg.To)
if err != nil {
return EthTxArgs{}, err
}
to = &addr
if len(msg.Params) == 0 {
if msg.Method != builtintypes.MethodSend {
return EthTxArgs{}, xerrors.Errorf("cannot invoke method %d on non-EAM actor without params", msg.Method)
}
} else {
if msg.Method != builtintypes.MethodsEVM.InvokeContract {
return EthTxArgs{},
xerrors.Errorf("invalid methodnum %d: only allowed non-send method is InvokeContract(%d)",
msg.Method,
builtintypes.MethodsEVM.InvokeContract)
}
params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params)))
if err != nil {
return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err)
}
if len(params) == 0 {
// Otherwise, we don't get a guaranteed round-trip.
return EthTxArgs{}, xerrors.Errorf("cannot invoke contracts with empty parameters from an eth-account")
}
}
}
if paramsReader.Len() != 0 {
return EthTxArgs{}, xerrors.Errorf("extra data found in params")
}
return EthTxArgs{
ChainID: build.Eip155ChainId,
Nonce: int(msg.Nonce),
To: to,
Value: msg.Value,
Input: params,
MaxFeePerGas: msg.GasFeeCap,
MaxPriorityFeePerGas: msg.GasPremium,
GasLimit: int(msg.GasLimit),
}, nil
}
func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*types.Message, error) {
if tx.ChainID != build.Eip155ChainId {
return nil, xerrors.Errorf("unsupported chain id: %d", tx.ChainID)
}
var err error
method := builtintypes.MethodSend
var params []byte
var to address.Address
// nil indicates the EAM, only CreateExternal is allowed
if tx.To == nil {
to = builtintypes.EthereumAddressManagerActorAddr
method = builtintypes.MethodsEAM.CreateExternal
if len(tx.Input) == 0 {
return nil, xerrors.New("cannot call CreateExternal without params")
}
inputParams := abi.CborBytes(tx.Input)
params, err = actors.SerializeParams(&inputParams)
if err != nil {
return nil, fmt.Errorf("failed to serialize Create params: %w", err)
}
} else {
to, err = tx.To.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("failed to convert To into filecoin addr: %w", err)
}
if len(tx.Input) == 0 {
// Yes, this is redundant, but let's be sure what we're doing
method = builtintypes.MethodSend
params = make([]byte, 0)
} else {
// must be InvokeContract
method = builtintypes.MethodsEVM.InvokeContract
buf := new(bytes.Buffer)
if err = cbg.WriteByteArray(buf, tx.Input); err != nil {
return nil, xerrors.Errorf("failed to write input args: %w", err)
}
params = buf.Bytes()
}
}
return &types.Message{
Version: 0,
To: to,
From: from,
Nonce: uint64(tx.Nonce),
Value: tx.Value,
GasLimit: int64(tx.GasLimit),
GasFeeCap: tx.MaxFeePerGas,
GasPremium: tx.MaxPriorityFeePerGas,
Method: method,
Params: params,
}, nil
}
func (tx *EthTxArgs) ToSignedMessage() (*types.SignedMessage, error) {
from, err := tx.Sender()
if err != nil {
return nil, xerrors.Errorf("failed to calculate sender: %w", err)
}
unsignedMsg, err := tx.ToUnsignedMessage(from)
if err != nil {
return nil, xerrors.Errorf("failed to convert to unsigned msg: %w", err)
}
siggy, err := tx.Signature()
if err != nil {
return nil, xerrors.Errorf("failed to calculate signature: %w", err)
}
return &types.SignedMessage{
Message: *unsignedMsg,
Signature: *siggy,
}, nil
}
func (tx *EthTxArgs) HashedOriginalRlpMsg() ([]byte, error) {
msg, err := tx.ToRlpUnsignedMsg()
if err != nil {
return nil, err
}
hasher := sha3.NewLegacyKeccak256()
hasher.Write(msg)
hash := hasher.Sum(nil)
return hash, nil
}
func (tx *EthTxArgs) ToRlpUnsignedMsg() ([]byte, error) {
packed, err := tx.packTxFields()
if err != nil {
return nil, err
}
encoded, err := EncodeRLP(packed)
if err != nil {
return nil, err
}
return append([]byte{0x02}, encoded...), nil
}
func (tx *EthTxArgs) ToRlpSignedMsg() ([]byte, error) {
packed1, err := tx.packTxFields()
if err != nil {
return nil, err
}
packed2, err := tx.packSigFields()
if err != nil {
return nil, err
}
encoded, err := EncodeRLP(append(packed1, packed2...))
if err != nil {
return nil, err
}
return append([]byte{0x02}, encoded...), nil
}
func (tx *EthTxArgs) packTxFields() ([]interface{}, error) {
chainId, err := formatInt(tx.ChainID)
if err != nil {
return nil, err
}
nonce, err := formatInt(tx.Nonce)
if err != nil {
return nil, err
}
maxPriorityFeePerGas, err := formatBigInt(tx.MaxPriorityFeePerGas)
if err != nil {
return nil, err
}
maxFeePerGas, err := formatBigInt(tx.MaxFeePerGas)
if err != nil {
return nil, err
}
gasLimit, err := formatInt(tx.GasLimit)
if err != nil {
return nil, err
}
value, err := formatBigInt(tx.Value)
if err != nil {
return nil, err
}
res := []interface{}{
chainId,
nonce,
maxPriorityFeePerGas,
maxFeePerGas,
gasLimit,
formatEthAddr(tx.To),
value,
tx.Input,
[]interface{}{}, // access list
}
return res, nil
}
func (tx *EthTxArgs) packSigFields() ([]interface{}, error) {
r, err := formatBigInt(tx.R)
if err != nil {
return nil, err
}
s, err := formatBigInt(tx.S)
if err != nil {
return nil, err
}
v, err := formatBigInt(tx.V)
if err != nil {
return nil, err
}
res := []interface{}{v, r, s}
return res, nil
}
func (tx *EthTxArgs) Signature() (*typescrypto.Signature, error) {
r := tx.R.Int.Bytes()
s := tx.S.Int.Bytes()
v := tx.V.Int.Bytes()
sig := append([]byte{}, padLeadingZeros(r, 32)...)
sig = append(sig, padLeadingZeros(s, 32)...)
if len(v) == 0 {
sig = append(sig, 0)
} else {
sig = append(sig, v[0])
}
if len(sig) != 65 {
return nil, fmt.Errorf("signature is not 65 bytes")
}
return &typescrypto.Signature{
Type: typescrypto.SigTypeDelegated, Data: sig,
}, nil
}
func (tx *EthTxArgs) Sender() (address.Address, error) {
msg, err := tx.ToRlpUnsignedMsg()
if err != nil {
return address.Undef, err
}
hasher := sha3.NewLegacyKeccak256()
hasher.Write(msg)
hash := hasher.Sum(nil)
sig, err := tx.Signature()
if err != nil {
return address.Undef, err
}
pubk, err := gocrypto.EcRecover(hash, sig.Data)
if err != nil {
return address.Undef, err
}
ethAddr, err := EthAddressFromPubKey(pubk)
if err != nil {
return address.Undef, err
}
ea, err := CastEthAddress(ethAddr)
if err != nil {
return address.Undef, err
}
return ea.ToFilecoinAddress()
}
func RecoverSignature(sig typescrypto.Signature) (r, s, v EthBigInt, err error) {
if sig.Type != typescrypto.SigTypeDelegated {
return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("RecoverSignature only supports Delegated signature")
}
if len(sig.Data) != 65 {
return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("signature should be 65 bytes long, but got %d bytes", len(sig.Data))
}
r_, err := parseBigInt(sig.Data[0:32])
if err != nil {
return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse r into EthBigInt")
}
s_, err := parseBigInt(sig.Data[32:64])
if err != nil {
return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse s into EthBigInt")
}
v_, err := parseBigInt([]byte{sig.Data[64]})
if err != nil {
return EthBigIntZero, EthBigIntZero, EthBigIntZero, fmt.Errorf("cannot parse v into EthBigInt")
}
return EthBigInt(r_), EthBigInt(s_), EthBigInt(v_), nil
}
func parseEip1559Tx(data []byte) (*EthTxArgs, error) {
if data[0] != 2 {
return nil, fmt.Errorf("not an EIP-1559 transaction: first byte is not 2")
}
d, err := DecodeRLP(data[1:])
if err != nil {
return nil, err
}
decoded, ok := d.([]interface{})
if !ok {
return nil, fmt.Errorf("not an EIP-1559 transaction: decoded data is not a list")
}
if len(decoded) != 12 {
return nil, fmt.Errorf("not an EIP-1559 transaction: should have 12 elements in the rlp list")
}
chainId, err := parseInt(decoded[0])
if err != nil {
return nil, err
}
nonce, err := parseInt(decoded[1])
if err != nil {
return nil, err
}
maxPriorityFeePerGas, err := parseBigInt(decoded[2])
if err != nil {
return nil, err
}
maxFeePerGas, err := parseBigInt(decoded[3])
if err != nil {
return nil, err
}
gasLimit, err := parseInt(decoded[4])
if err != nil {
return nil, err
}
to, err := parseEthAddr(decoded[5])
if err != nil {
return nil, err
}
value, err := parseBigInt(decoded[6])
if err != nil {
return nil, err
}
input, err := parseBytes(decoded[7])
if err != nil {
return nil, err
}
accessList, ok := decoded[8].([]interface{})
if !ok || (ok && len(accessList) != 0) {
return nil, fmt.Errorf("access list should be an empty list")
}
r, err := parseBigInt(decoded[10])
if err != nil {
return nil, err
}
s, err := parseBigInt(decoded[11])
if err != nil {
return nil, err
}
v, err := parseBigInt(decoded[9])
if err != nil {
return nil, err
}
// EIP-1559 and EIP-2930 transactions only support 0 or 1 for v
// Legacy and EIP-155 transactions support other values
// https://github.com/ethers-io/ethers.js/blob/56fabe987bb8c1e4891fdf1e5d3fe8a4c0471751/packages/transactions/src.ts/index.ts#L333
if !v.Equals(big.NewInt(0)) && !v.Equals(big.NewInt(1)) {
return nil, fmt.Errorf("EIP-1559 transactions only support 0 or 1 for v")
}
args := EthTxArgs{
ChainID: chainId,
Nonce: nonce,
To: to,
MaxPriorityFeePerGas: maxPriorityFeePerGas,
MaxFeePerGas: maxFeePerGas,
GasLimit: gasLimit,
Value: value,
Input: input,
V: v,
R: r,
S: s,
}
return &args, nil
}
func ParseEthTxArgs(data []byte) (*EthTxArgs, error) {
if len(data) == 0 {
return nil, fmt.Errorf("empty data")
}
if data[0] > 0x7f {
// legacy transaction
return nil, fmt.Errorf("legacy transaction is not supported")
}
if data[0] == 1 {
// EIP-2930
return nil, fmt.Errorf("EIP-2930 transaction is not supported")
}
if data[0] == Eip1559TxType {
// EIP-1559
return parseEip1559Tx(data)
}
return nil, fmt.Errorf("unsupported transaction type")
}
func padLeadingZeros(data []byte, length int) []byte {
if len(data) >= length {
return data
}
zeros := make([]byte, length-len(data))
return append(zeros, data...)
}
func removeLeadingZeros(data []byte) []byte {
firstNonZeroIndex := len(data)
for i, b := range data {
if b > 0 {
firstNonZeroIndex = i
break
}
}
return data[firstNonZeroIndex:]
}
func formatInt(val int) ([]byte, error) {
buf := new(bytes.Buffer)
err := binary.Write(buf, binary.BigEndian, int64(val))
if err != nil {
return nil, err
}
return removeLeadingZeros(buf.Bytes()), nil
}
func formatEthAddr(addr *EthAddress) []byte {
if addr == nil {
return nil
}
return addr[:]
}
func formatBigInt(val big.Int) ([]byte, error) {
b, err := val.Bytes()
if err != nil {
return nil, err
}
return removeLeadingZeros(b), nil
}
func parseInt(v interface{}) (int, error) {
data, ok := v.([]byte)
if !ok {
return 0, fmt.Errorf("cannot parse interface to int: input is not a byte array")
}
if len(data) == 0 {
return 0, nil
}
if len(data) > 8 {
return 0, fmt.Errorf("cannot parse interface to int: length is more than 8 bytes")
}
var value int64
r := bytes.NewReader(append(make([]byte, 8-len(data)), data...))
if err := binary.Read(r, binary.BigEndian, &value); err != nil {
return 0, fmt.Errorf("cannot parse interface to EthUint64: %w", err)
}
return int(value), nil
}
func parseBigInt(v interface{}) (big.Int, error) {
data, ok := v.([]byte)
if !ok {
return big.Zero(), fmt.Errorf("cannot parse interface to big.Int: input is not a byte array")
}
if len(data) == 0 {
return big.Zero(), nil
}
var b mathbig.Int
b.SetBytes(data)
return big.NewFromGo(&b), nil
}
func parseBytes(v interface{}) ([]byte, error) {
val, ok := v.([]byte)
if !ok {
return nil, fmt.Errorf("cannot parse interface into bytes: input is not a byte array")
}
return val, nil
}
func parseEthAddr(v interface{}) (*EthAddress, error) {
b, err := parseBytes(v)
if err != nil {
return nil, err
}
if len(b) == 0 {
return nil, nil
}
addr, err := CastEthAddress(b)
if err != nil {
return nil, err
}
return &addr, nil
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,600 @@
package ethtypes
import (
"bytes"
"encoding/binary"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
mathbig "math/big"
"strconv"
"strings"
"github.com/ipfs/go-cid"
"github.com/multiformats/go-multihash"
"github.com/multiformats/go-varint"
"golang.org/x/crypto/sha3"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/lotus/build"
)
var (
EthTopic1 = "topic1"
EthTopic2 = "topic2"
EthTopic3 = "topic3"
EthTopic4 = "topic4"
)
var ErrInvalidAddress = errors.New("invalid Filecoin Eth address")
type EthUint64 uint64
func (e EthUint64) MarshalJSON() ([]byte, error) {
if e == 0 {
return json.Marshal("0x0")
}
return json.Marshal(fmt.Sprintf("0x%x", e))
}
func (e *EthUint64) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
parsedInt, err := strconv.ParseUint(strings.Replace(s, "0x", "", -1), 16, 64)
if err != nil {
return err
}
eint := EthUint64(parsedInt)
*e = eint
return nil
}
func EthUint64FromHex(s string) (EthUint64, error) {
parsedInt, err := strconv.ParseUint(strings.Replace(s, "0x", "", -1), 16, 64)
if err != nil {
return EthUint64(0), err
}
return EthUint64(parsedInt), nil
}
// EthBigInt represents a large integer whose zero value serializes to "0x0".
type EthBigInt big.Int
var EthBigIntZero = EthBigInt{Int: big.Zero().Int}
func (e EthBigInt) MarshalJSON() ([]byte, error) {
if e.Int == nil || e.Int.BitLen() == 0 {
return json.Marshal("0x0")
}
return json.Marshal(fmt.Sprintf("0x%x", e.Int))
}
func (e *EthBigInt) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
replaced := strings.Replace(s, "0x", "", -1)
if len(replaced)%2 == 1 {
replaced = "0" + replaced
}
i := new(mathbig.Int)
i.SetString(replaced, 16)
*e = EthBigInt(big.NewFromGo(i))
return nil
}
// EthBytes represent arbitrary bytes. A nil or empty slice serializes to "0x".
type EthBytes []byte
func (e EthBytes) MarshalJSON() ([]byte, error) {
if len(e) == 0 {
return json.Marshal("0x")
}
s := hex.EncodeToString(e)
return json.Marshal("0x" + s)
}
func (e *EthBytes) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
s = strings.Replace(s, "0x", "", -1)
if len(s)%2 == 1 {
s = "0" + s
}
decoded, err := hex.DecodeString(s)
if err != nil {
return err
}
*e = decoded
return nil
}
type EthBlock struct {
Hash EthHash `json:"hash"`
ParentHash EthHash `json:"parentHash"`
Sha3Uncles EthHash `json:"sha3Uncles"`
Miner EthAddress `json:"miner"`
StateRoot EthHash `json:"stateRoot"`
TransactionsRoot EthHash `json:"transactionsRoot"`
ReceiptsRoot EthHash `json:"receiptsRoot"`
LogsBloom EthBytes `json:"logsBloom"`
Difficulty EthUint64 `json:"difficulty"`
TotalDifficulty EthUint64 `json:"totalDifficulty"`
Number EthUint64 `json:"number"`
GasLimit EthUint64 `json:"gasLimit"`
GasUsed EthUint64 `json:"gasUsed"`
Timestamp EthUint64 `json:"timestamp"`
Extradata []byte `json:"extraData"`
MixHash EthHash `json:"mixHash"`
Nonce EthNonce `json:"nonce"`
BaseFeePerGas EthBigInt `json:"baseFeePerGas"`
Size EthUint64 `json:"size"`
// can be []EthTx or []string depending on query params
Transactions []interface{} `json:"transactions"`
Uncles []EthHash `json:"uncles"`
}
var (
EmptyEthBloom = [256]byte{}
EmptyEthHash = EthHash{}
EmptyEthInt = EthUint64(0)
EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0}
)
func NewEthBlock() EthBlock {
return EthBlock{
Sha3Uncles: EmptyEthHash,
StateRoot: EmptyEthHash,
TransactionsRoot: EmptyEthHash,
ReceiptsRoot: EmptyEthHash,
Difficulty: EmptyEthInt,
LogsBloom: EmptyEthBloom[:],
Extradata: []byte{},
MixHash: EmptyEthHash,
Nonce: EmptyEthNonce,
GasLimit: EthUint64(build.BlockGasLimit), // TODO we map Ethereum blocks to Filecoin tipsets; this is inconsistent.
Uncles: []EthHash{},
Transactions: []interface{}{},
}
}
type EthCall struct {
From *EthAddress `json:"from"`
To *EthAddress `json:"to"`
Gas EthUint64 `json:"gas"`
GasPrice EthBigInt `json:"gasPrice"`
Value EthBigInt `json:"value"`
Data EthBytes `json:"data"`
}
func (c *EthCall) UnmarshalJSON(b []byte) error {
type TempEthCall EthCall
var params TempEthCall
if err := json.Unmarshal(b, &params); err != nil {
return err
}
*c = EthCall(params)
return nil
}
const (
EthAddressLength = 20
EthHashLength = 32
)
type EthNonce [8]byte
func (n EthNonce) String() string {
return "0x" + hex.EncodeToString(n[:])
}
func (n EthNonce) MarshalJSON() ([]byte, error) {
return json.Marshal(n.String())
}
func (n *EthNonce) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
s = strings.Replace(s, "0x", "", -1)
if len(s)%2 == 1 {
s = "0" + s
}
decoded, err := hex.DecodeString(s)
if err != nil {
return err
}
copy(n[:], decoded[:8])
return nil
}
type EthAddress [EthAddressLength]byte
// EthAddressFromPubKey returns the Ethereum address corresponding to an
// uncompressed secp256k1 public key.
func EthAddressFromPubKey(pubk []byte) ([]byte, error) {
// if we get an uncompressed public key (that's what we get from the library,
// but putting this check here for defensiveness), strip the prefix
const pubKeyLen = 65
if len(pubk) != pubKeyLen {
return nil, fmt.Errorf("public key should have %d in length, but got %d", pubKeyLen, len(pubk))
}
if pubk[0] != 0x04 {
return nil, fmt.Errorf("expected first byte of secp256k1 to be 0x04 (uncompressed)")
}
pubk = pubk[1:]
// Calculate the Ethereum address based on the keccak hash of the pubkey.
hasher := sha3.NewLegacyKeccak256()
hasher.Write(pubk)
ethAddr := hasher.Sum(nil)[12:]
return ethAddr, nil
}
func EthAddressFromFilecoinAddress(addr address.Address) (EthAddress, error) {
switch addr.Protocol() {
case address.ID:
id, err := address.IDFromAddress(addr)
if err != nil {
return EthAddress{}, err
}
var ethaddr EthAddress
ethaddr[0] = 0xff
binary.BigEndian.PutUint64(ethaddr[12:], id)
return ethaddr, nil
case address.Delegated:
payload := addr.Payload()
namespace, n, err := varint.FromUvarint(payload)
if err != nil {
return EthAddress{}, xerrors.Errorf("invalid delegated address namespace in: %s", addr)
}
payload = payload[n:]
if namespace == builtintypes.EthereumAddressManagerActorID {
return CastEthAddress(payload)
}
}
return EthAddress{}, ErrInvalidAddress
}
// ParseEthAddress parses an Ethereum address from a hex string.
func ParseEthAddress(s string) (EthAddress, error) {
b, err := decodeHexString(s, EthAddressLength)
if err != nil {
return EthAddress{}, err
}
var h EthAddress
copy(h[EthAddressLength-len(b):], b)
return h, nil
}
// CastEthAddress interprets bytes as an EthAddress, performing some basic checks.
func CastEthAddress(b []byte) (EthAddress, error) {
var a EthAddress
if len(b) != EthAddressLength {
return EthAddress{}, xerrors.Errorf("cannot parse bytes into an EthAddress: incorrect input length")
}
copy(a[:], b[:])
return a, nil
}
func (ea EthAddress) String() string {
return "0x" + hex.EncodeToString(ea[:])
}
func (ea EthAddress) MarshalJSON() ([]byte, error) {
return json.Marshal(ea.String())
}
func (ea *EthAddress) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
addr, err := ParseEthAddress(s)
if err != nil {
return err
}
copy(ea[:], addr[:])
return nil
}
func (ea EthAddress) IsMaskedID() bool {
idmask := [12]byte{0xff}
return bytes.Equal(ea[:12], idmask[:])
}
func (ea EthAddress) ToFilecoinAddress() (address.Address, error) {
if ea.IsMaskedID() {
// This is a masked ID address.
id := binary.BigEndian.Uint64(ea[12:])
return address.NewIDAddress(id)
}
// Otherwise, translate the address into an address controlled by the
// Ethereum Address Manager.
addr, err := address.NewDelegatedAddress(builtintypes.EthereumAddressManagerActorID, ea[:])
if err != nil {
return address.Undef, fmt.Errorf("failed to translate supplied address (%s) into a "+
"Filecoin f4 address: %w", hex.EncodeToString(ea[:]), err)
}
return addr, nil
}
type EthHash [EthHashLength]byte
func (h EthHash) MarshalJSON() ([]byte, error) {
return json.Marshal(h.String())
}
func (h *EthHash) UnmarshalJSON(b []byte) error {
var s string
if err := json.Unmarshal(b, &s); err != nil {
return err
}
hash, err := ParseEthHash(s)
if err != nil {
return err
}
copy(h[:], hash[:])
return nil
}
func decodeHexString(s string, expectedLen int) ([]byte, error) {
// Strip the leading 0x or 0X prefix since hex.DecodeString does not support it.
if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
s = s[2:]
}
// Sometimes clients will omit a leading zero in a byte; pad so we can decode correctly.
if len(s)%2 == 1 {
s = "0" + s
}
if len(s) != expectedLen*2 {
return nil, xerrors.Errorf("expected hex string length sans prefix %d, got %d", expectedLen*2, len(s))
}
b, err := hex.DecodeString(s)
if err != nil {
return nil, xerrors.Errorf("cannot parse hex value: %w", err)
}
return b, nil
}
func EthHashFromCid(c cid.Cid) (EthHash, error) {
return ParseEthHash(c.Hash().HexString()[8:])
}
func ParseEthHash(s string) (EthHash, error) {
b, err := decodeHexString(s, EthHashLength)
if err != nil {
return EthHash{}, err
}
var h EthHash
copy(h[EthHashLength-len(b):], b)
return h, nil
}
func (h EthHash) String() string {
return "0x" + hex.EncodeToString(h[:])
}
func (h EthHash) ToCid() cid.Cid {
// err is always nil
mh, _ := multihash.EncodeName(h[:], "blake2b-256")
return cid.NewCidV1(cid.DagCBOR, mh)
}
type EthFeeHistory struct {
OldestBlock uint64 `json:"oldestBlock"`
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
GasUsedRatio []float64 `json:"gasUsedRatio"`
Reward *[][]EthBigInt `json:"reward,omitempty"`
}
type EthFilterID EthHash
// An opaque identifier generated by the Lotus node to refer to an active subscription.
type EthSubscriptionID EthHash
type EthFilterSpec struct {
// Interpreted as an epoch or one of "latest" for last mined block, "earliest" for first,
// "pending" for not yet committed messages.
// Optional, default: "latest".
FromBlock *string `json:"fromBlock,omitempty"`
// Interpreted as an epoch or one of "latest" for last mined block, "earliest" for first,
// "pending" for not yet committed messages.
// Optional, default: "latest".
ToBlock *string `json:"toBlock,omitempty"`
// Actor address or a list of addresses from which event logs should originate.
// Optional, default nil.
// The JSON decoding must treat a string as equivalent to an array with one value, for example
// "0x8888f1f195afa192cfee86069858" must be decoded as [ "0x8888f1f195afa192cfee86069858" ]
Address EthAddressList `json:"address"`
// List of topics to be matched.
// Optional, default: empty list
Topics EthTopicSpec `json:"topics"`
// Restricts event logs returned to those emitted from messages contained in this tipset.
// If BlockHash is present in in the filter criteria, then neither FromBlock nor ToBlock are allowed.
// Added in EIP-234
BlockHash *EthHash `json:"blockHash,omitempty"`
}
// EthAddressSpec represents a list of addresses.
// The JSON decoding must treat a string as equivalent to an array with one value, for example
// "0x8888f1f195afa192cfee86069858" must be decoded as [ "0x8888f1f195afa192cfee86069858" ]
type EthAddressList []EthAddress
func (e *EthAddressList) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte{'n', 'u', 'l', 'l'}) {
return nil
}
if len(b) > 0 && b[0] == '[' {
var addrs []EthAddress
err := json.Unmarshal(b, &addrs)
if err != nil {
return err
}
*e = addrs
return nil
}
var addr EthAddress
err := json.Unmarshal(b, &addr)
if err != nil {
return err
}
*e = []EthAddress{addr}
return nil
}
// TopicSpec represents a specification for matching by topic. An empty spec means all topics
// will be matched. Otherwise topics are matched conjunctively in the first dimension of the
// slice and disjunctively in the second dimension. Topics are matched in order.
// An event log with topics [A, B] will be matched by the following topic specs:
// [] "all"
// [[A]] "A in first position (and anything after)"
// [nil, [B] ] "anything in first position AND B in second position (and anything after)"
// [[A], [B]] "A in first position AND B in second position (and anything after)"
// [[A, B], [A, B]] "(A OR B) in first position AND (A OR B) in second position (and anything after)"
//
// The JSON decoding must treat string values as equivalent to arrays with one value, for example
// { "A", [ "B", "C" ] } must be decoded as [ [ A ], [ B, C ] ]
type EthTopicSpec []EthHashList
// EthHashList represents a list of EthHashes.
// The JSON decoding treats string values as equivalent to arrays with one value.
type EthHashList []EthHash
func (e *EthHashList) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte{'n', 'u', 'l', 'l'}) {
return nil
}
if len(b) > 0 && b[0] == '[' {
var hashes []EthHash
err := json.Unmarshal(b, &hashes)
if err != nil {
return err
}
*e = hashes
return nil
}
var hash EthHash
err := json.Unmarshal(b, &hash)
if err != nil {
return err
}
*e = []EthHash{hash}
return nil
}
// FilterResult represents the response from executing a filter: a list of block hashes, a list of transaction hashes
// or a list of logs
// This is a union type. Only one field will be populated.
// The JSON encoding must produce an array of the populated field.
type EthFilterResult struct {
Results []interface{}
}
func (h EthFilterResult) MarshalJSON() ([]byte, error) {
if h.Results != nil {
return json.Marshal(h.Results)
}
return []byte{'[', ']'}, nil
}
func (h *EthFilterResult) UnmarshalJSON(b []byte) error {
if bytes.Equal(b, []byte{'n', 'u', 'l', 'l'}) {
return nil
}
err := json.Unmarshal(b, &h.Results)
return err
}
// EthLog represents the results of an event filter execution.
type EthLog struct {
// Address is the address of the actor that produced the event log.
Address EthAddress `json:"address"`
// Data is the value of the event log, excluding topics
Data EthBytes `json:"data"`
// List of topics associated with the event log.
Topics []EthBytes `json:"topics"`
// Following fields are derived from the transaction containing the log
// Indicates whether the log was removed due to a chain reorganization.
Removed bool `json:"removed"`
// LogIndex is the index of the event log in the sequence of events produced by the message execution.
// (this is the index in the events AMT on the message receipt)
LogIndex EthUint64 `json:"logIndex"`
// TransactionIndex is the index in the tipset of the transaction that produced the event log.
// The index corresponds to the sequence of messages produced by ChainGetParentMessages
TransactionIndex EthUint64 `json:"transactionIndex"`
// TransactionHash is the cid of the message that produced the event log.
TransactionHash EthHash `json:"transactionHash"`
// BlockHash is the hash of the tipset containing the message that produced the log.
BlockHash EthHash `json:"blockHash"`
// BlockNumber is the epoch of the tipset containing the message.
BlockNumber EthUint64 `json:"blockNumber"`
}
type EthSubscriptionParams struct {
// List of topics to be matched.
// Optional, default: empty list
Topics EthTopicSpec `json:"topics,omitempty"`
}
type EthSubscriptionResponse struct {
// The persistent identifier for the subscription which can be used to unsubscribe.
SubscriptionID EthSubscriptionID `json:"subscription"`
// The object matching the subscription. This may be a Block (tipset), a Transaction (message) or an EthLog
Result interface{} `json:"result"`
}
func GetContractEthAddressFromCode(sender EthAddress, salt [32]byte, initcode []byte) (EthAddress, error) {
hasher := sha3.NewLegacyKeccak256()
hasher.Write(initcode)
inithash := hasher.Sum(nil)
hasher.Reset()
hasher.Write([]byte{0xff})
hasher.Write(sender[:])
hasher.Write(salt[:])
hasher.Write(inithash)
ethAddr, err := CastEthAddress(hasher.Sum(nil)[12:])
if err != nil {
return [20]byte{}, err
}
return ethAddr, nil
}

View File

@ -0,0 +1,384 @@
package ethtypes
import (
"encoding/json"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/big"
)
type TestCase struct {
Input interface{}
Output interface{}
}
func TestEthIntMarshalJSON(t *testing.T) {
// https://ethereum.org/en/developers/docs/apis/json-rpc/#quantities-encoding
testcases := []TestCase{
{EthUint64(0), []byte("\"0x0\"")},
{EthUint64(65), []byte("\"0x41\"")},
{EthUint64(1024), []byte("\"0x400\"")},
}
for _, tc := range testcases {
j, err := tc.Input.(EthUint64).MarshalJSON()
require.Nil(t, err)
require.Equal(t, j, tc.Output)
}
}
func TestEthIntUnmarshalJSON(t *testing.T) {
testcases := []TestCase{
{[]byte("\"0x0\""), EthUint64(0)},
{[]byte("\"0x41\""), EthUint64(65)},
{[]byte("\"0x400\""), EthUint64(1024)},
}
for _, tc := range testcases {
var i EthUint64
err := i.UnmarshalJSON(tc.Input.([]byte))
require.Nil(t, err)
require.Equal(t, i, tc.Output)
}
}
func TestEthBigIntMarshalJSON(t *testing.T) {
testcases := []TestCase{
{EthBigInt(big.NewInt(0)), []byte("\"0x0\"")},
{EthBigInt(big.NewInt(65)), []byte("\"0x41\"")},
{EthBigInt(big.NewInt(1024)), []byte("\"0x400\"")},
{EthBigInt(big.Int{}), []byte("\"0x0\"")},
}
for _, tc := range testcases {
j, err := tc.Input.(EthBigInt).MarshalJSON()
require.Nil(t, err)
require.Equal(t, j, tc.Output)
}
}
func TestEthBigIntUnmarshalJSON(t *testing.T) {
testcases := []TestCase{
{[]byte("\"0x0\""), EthBigInt(big.MustFromString("0"))},
{[]byte("\"0x41\""), EthBigInt(big.MustFromString("65"))},
{[]byte("\"0x400\""), EthBigInt(big.MustFromString("1024"))},
{[]byte("\"0xff1000000000000000000000000\""), EthBigInt(big.MustFromString("323330131220712761719252861321216"))},
}
for _, tc := range testcases {
var i EthBigInt
err := i.UnmarshalJSON(tc.Input.([]byte))
require.Nil(t, err)
require.Equal(t, i, tc.Output)
}
}
func TestEthHash(t *testing.T) {
testcases := []string{
`"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`,
`"0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"`,
}
for _, hash := range testcases {
var h EthHash
err := h.UnmarshalJSON([]byte(hash))
require.Nil(t, err)
require.Equal(t, h.String(), strings.Replace(hash, `"`, "", -1))
c := h.ToCid()
h1, err := EthHashFromCid(c)
require.Nil(t, err)
require.Equal(t, h, h1)
}
}
func TestEthAddr(t *testing.T) {
testcases := []string{
strings.ToLower(`"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"`),
strings.ToLower(`"0x2C2EC67e3e1FeA8e4A39601cB3A3Cd44f5fa830d"`),
strings.ToLower(`"0x01184F793982104363F9a8a5845743f452dE0586"`),
}
for _, addr := range testcases {
var a EthAddress
err := a.UnmarshalJSON([]byte(addr))
require.Nil(t, err)
require.Equal(t, a.String(), strings.Replace(addr, `"`, "", -1))
}
}
func TestParseEthAddr(t *testing.T) {
testcases := []uint64{
1, 2, 3, 100, 101,
}
for _, id := range testcases {
addr, err := address.NewIDAddress(id)
require.Nil(t, err)
eaddr, err := EthAddressFromFilecoinAddress(addr)
require.Nil(t, err)
faddr, err := eaddr.ToFilecoinAddress()
require.Nil(t, err)
require.Equal(t, addr, faddr)
}
}
func TestUnmarshalEthCall(t *testing.T) {
data := `{"from":"0x4D6D86b31a112a05A473c4aE84afaF873f632325","to":"0xFe01CC39f5Ae8553D6914DBb9dC27D219fa22D7f","gas":"0x5","gasPrice":"0x6","value":"0x123","data":""}`
var c EthCall
err := c.UnmarshalJSON([]byte(data))
require.Nil(t, err)
}
func TestUnmarshalEthBytes(t *testing.T) {
testcases := []string{
`"0x00"`,
strings.ToLower(`"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"`),
strings.ToLower(`"0x2C2EC67e3e1FeA8e4A39601cB3A3Cd44f5fa830d"`),
strings.ToLower(`"0x01184F793982104363F9a8a5845743f452dE0586"`),
}
for _, tc := range testcases {
var s EthBytes
err := s.UnmarshalJSON([]byte(tc))
require.Nil(t, err)
data, err := s.MarshalJSON()
require.Nil(t, err)
require.Equal(t, string(data), tc)
}
}
func TestEthFilterResultMarshalJSON(t *testing.T) {
hash1, err := ParseEthHash("013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184")
require.NoError(t, err, "eth hash")
hash2, err := ParseEthHash("ab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738")
require.NoError(t, err, "eth hash")
addr, err := ParseEthAddress("d4c5fb16488Aa48081296299d54b0c648C9333dA")
require.NoError(t, err, "eth address")
log := EthLog{
Removed: true,
LogIndex: 5,
TransactionIndex: 45,
TransactionHash: hash1,
BlockHash: hash2,
BlockNumber: 53,
Topics: []EthBytes{hash1[:]},
Data: EthBytes(hash1[:]),
Address: addr,
}
logjson, err := json.Marshal(log)
require.NoError(t, err, "log json")
testcases := []struct {
res EthFilterResult
want string
}{
{
res: EthFilterResult{},
want: "[]",
},
{
res: EthFilterResult{
Results: []any{hash1, hash2},
},
want: `["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184","0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"]`,
},
{
res: EthFilterResult{
Results: []any{hash1, hash2},
},
want: `["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184","0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"]`,
},
{
res: EthFilterResult{
Results: []any{log},
},
want: `[` + string(logjson) + `]`,
},
}
for _, tc := range testcases {
tc := tc
t.Run("", func(t *testing.T) {
data, err := json.Marshal(tc.res)
require.NoError(t, err)
require.Equal(t, tc.want, string(data))
})
}
}
func TestEthFilterSpecUnmarshalJSON(t *testing.T) {
hash1, err := ParseEthHash("013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184")
require.NoError(t, err, "eth hash")
hash2, err := ParseEthHash("ab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738")
require.NoError(t, err, "eth hash")
addr, err := ParseEthAddress("d4c5fb16488Aa48081296299d54b0c648C9333dA")
require.NoError(t, err, "eth address")
pstring := func(s string) *string { return &s }
phash := func(h EthHash) *EthHash { return &h }
testcases := []struct {
input string
want EthFilterSpec
}{
{
input: `{"fromBlock":"latest"}`,
want: EthFilterSpec{FromBlock: pstring("latest")},
},
{
input: `{"toBlock":"pending"}`,
want: EthFilterSpec{ToBlock: pstring("pending")},
},
{
input: `{"address":["0xd4c5fb16488Aa48081296299d54b0c648C9333dA"]}`,
want: EthFilterSpec{Address: EthAddressList{addr}},
},
{
input: `{"address":"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"}`,
want: EthFilterSpec{Address: EthAddressList{addr}},
},
{
input: `{"blockHash":"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"}`,
want: EthFilterSpec{BlockHash: phash(hash1)},
},
{
input: `{"topics":["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"]}`,
want: EthFilterSpec{
Topics: EthTopicSpec{
{hash1},
},
},
},
{
input: `{"topics":["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184","0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"]}`,
want: EthFilterSpec{
Topics: EthTopicSpec{
{hash1},
{hash2},
},
},
},
{
input: `{"topics":[null, ["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184","0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"]]}`,
want: EthFilterSpec{
Topics: EthTopicSpec{
nil,
{hash1, hash2},
},
},
},
{
input: `{"topics":[null, "0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"]}`,
want: EthFilterSpec{
Topics: EthTopicSpec{
nil,
{hash1},
},
},
},
}
for _, tc := range testcases {
var got EthFilterSpec
err := json.Unmarshal([]byte(tc.input), &got)
require.NoError(t, err)
require.Equal(t, tc.want, got)
}
}
func TestEthAddressListUnmarshalJSON(t *testing.T) {
addr1, err := ParseEthAddress("d4c5fb16488Aa48081296299d54b0c648C9333dA")
require.NoError(t, err, "eth address")
addr2, err := ParseEthAddress("abbbfb16488Aa48081296299d54b0c648C9333dA")
require.NoError(t, err, "eth address")
testcases := []struct {
input string
want EthAddressList
}{
{
input: `["0xd4c5fb16488Aa48081296299d54b0c648C9333dA"]`,
want: EthAddressList{addr1},
},
{
input: `["0xd4c5fb16488Aa48081296299d54b0c648C9333dA","abbbfb16488Aa48081296299d54b0c648C9333dA"]`,
want: EthAddressList{addr1, addr2},
},
{
input: `"0xd4c5fb16488Aa48081296299d54b0c648C9333dA"`,
want: EthAddressList{addr1},
},
{
input: `[]`,
want: EthAddressList{},
},
{
input: `null`,
want: EthAddressList(nil),
},
}
for _, tc := range testcases {
tc := tc
t.Run("", func(t *testing.T) {
var got EthAddressList
err := json.Unmarshal([]byte(tc.input), &got)
require.NoError(t, err)
require.Equal(t, tc.want, got)
})
}
}
func TestEthHashListUnmarshalJSON(t *testing.T) {
hash1, err := ParseEthHash("013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184")
require.NoError(t, err, "eth hash")
hash2, err := ParseEthHash("ab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738")
require.NoError(t, err, "eth hash")
testcases := []struct {
input string
want *EthHashList
}{
{
input: `["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"]`,
want: &EthHashList{hash1},
},
{
input: `["0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184","0xab8653edf9f51785664a643b47605a7ba3d917b5339a0724e7642c114d0e4738"]`,
want: &EthHashList{hash1, hash2},
},
{
input: `"0x013dbb9442ca9667baccc6230fcd5c1c4b2d4d2870f4bd20681d4d47cfd15184"`,
want: &EthHashList{hash1},
},
{
input: `null`,
want: nil,
},
}
for _, tc := range testcases {
var got *EthHashList
err := json.Unmarshal([]byte(tc.input), &got)
require.NoError(t, err)
require.Equal(t, tc.want, got)
}
}

182
chain/types/ethtypes/rlp.go Normal file
View File

@ -0,0 +1,182 @@
package ethtypes
import (
"bytes"
"encoding/binary"
"fmt"
"golang.org/x/xerrors"
)
// maxListElements restricts the amount of RLP list elements we'll read.
// The ETH API only ever reads EIP-1559 transactions, which are bounded by
// 12 elements exactly, so we play it safe and set exactly that limit here.
const maxListElements = 12
func EncodeRLP(val interface{}) ([]byte, error) {
return encodeRLP(val)
}
func encodeRLPListItems(list []interface{}) (result []byte, err error) {
res := []byte{}
for _, elem := range list {
encoded, err := encodeRLP(elem)
if err != nil {
return nil, err
}
res = append(res, encoded...)
}
return res, nil
}
func encodeLength(length int) (lenInBytes []byte, err error) {
if length == 0 {
return nil, fmt.Errorf("cannot encode length: length should be larger than 0")
}
buf := new(bytes.Buffer)
err = binary.Write(buf, binary.BigEndian, int64(length))
if err != nil {
return nil, err
}
firstNonZeroIndex := len(buf.Bytes()) - 1
for i, b := range buf.Bytes() {
if b != 0 {
firstNonZeroIndex = i
break
}
}
res := buf.Bytes()[firstNonZeroIndex:]
return res, nil
}
func encodeRLP(val interface{}) ([]byte, error) {
switch data := val.(type) {
case []byte:
if len(data) == 1 && data[0] <= 0x7f {
return data, nil
} else if len(data) <= 55 {
prefix := byte(0x80 + len(data))
return append([]byte{prefix}, data...), nil
} else {
lenInBytes, err := encodeLength(len(data))
if err != nil {
return nil, err
}
prefix := byte(0xb7 + len(lenInBytes))
return append(
[]byte{prefix},
append(lenInBytes, data...)...,
), nil
}
case []interface{}:
encodedList, err := encodeRLPListItems(data)
if err != nil {
return nil, err
}
if len(encodedList) <= 55 {
prefix := byte(0xc0 + len(encodedList))
return append(
[]byte{prefix},
encodedList...,
), nil
}
lenInBytes, err := encodeLength(len(encodedList))
if err != nil {
return nil, err
}
prefix := byte(0xf7 + len(lenInBytes))
return append(
[]byte{prefix},
append(lenInBytes, encodedList...)...,
), nil
default:
return nil, fmt.Errorf("input data should either be a list or a byte array")
}
}
func DecodeRLP(data []byte) (interface{}, error) {
res, consumed, err := decodeRLP(data)
if err != nil {
return nil, err
}
if consumed != len(data) {
return nil, xerrors.Errorf("invalid rlp data: length %d, consumed %d", len(data), consumed)
}
return res, nil
}
func decodeRLP(data []byte) (res interface{}, consumed int, err error) {
if len(data) == 0 {
return data, 0, xerrors.Errorf("invalid rlp data: data cannot be empty")
}
if data[0] >= 0xf8 {
listLenInBytes := int(data[0]) - 0xf7
listLen, err := decodeLength(data[1:], listLenInBytes)
if err != nil {
return nil, 0, err
}
if 1+listLenInBytes+listLen > len(data) {
return nil, 0, xerrors.Errorf("invalid rlp data: out of bound while parsing list")
}
result, err := decodeListElems(data[1+listLenInBytes:], listLen)
return result, 1 + listLenInBytes + listLen, err
} else if data[0] >= 0xc0 {
length := int(data[0]) - 0xc0
result, err := decodeListElems(data[1:], length)
return result, 1 + length, err
} else if data[0] >= 0xb8 {
strLenInBytes := int(data[0]) - 0xb7
strLen, err := decodeLength(data[1:], strLenInBytes)
if err != nil {
return nil, 0, err
}
totalLen := 1 + strLenInBytes + strLen
if totalLen > len(data) {
return nil, 0, xerrors.Errorf("invalid rlp data: out of bound while parsing string")
}
return data[1+strLenInBytes : totalLen], totalLen, nil
} else if data[0] >= 0x80 {
length := int(data[0]) - 0x80
if 1+length > len(data) {
return nil, 0, xerrors.Errorf("invalid rlp data: out of bound while parsing string")
}
return data[1 : 1+length], 1 + length, nil
}
return []byte{data[0]}, 1, nil
}
func decodeLength(data []byte, lenInBytes int) (length int, err error) {
if lenInBytes > len(data) || lenInBytes > 8 {
return 0, xerrors.Errorf("invalid rlp data: out of bound while parsing list length")
}
var decodedLength int64
r := bytes.NewReader(append(make([]byte, 8-lenInBytes), data[:lenInBytes]...))
if err := binary.Read(r, binary.BigEndian, &decodedLength); err != nil {
return 0, xerrors.Errorf("invalid rlp data: cannot parse string length: %w", err)
}
if lenInBytes+int(decodedLength) > len(data) {
return 0, xerrors.Errorf("invalid rlp data: out of bound while parsing list")
}
return int(decodedLength), nil
}
func decodeListElems(data []byte, length int) (res []interface{}, err error) {
totalConsumed := 0
result := []interface{}{}
for i := 0; totalConsumed < length && i < maxListElements; i++ {
elem, consumed, err := decodeRLP(data[totalConsumed:])
if err != nil {
return nil, xerrors.Errorf("invalid rlp data: cannot decode list element: %w", err)
}
totalConsumed += consumed
result = append(result, elem)
}
if totalConsumed != length {
return nil, xerrors.Errorf("invalid rlp data: incorrect list length")
}
return result, nil
}

View File

@ -0,0 +1,190 @@
package ethtypes
import (
"encoding/hex"
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
)
func TestEncode(t *testing.T) {
testcases := []TestCase{
{[]byte(""), mustDecodeHex("0x80")},
{mustDecodeHex("0x01"), mustDecodeHex("0x01")},
{mustDecodeHex("0xaa"), mustDecodeHex("0x81aa")},
{mustDecodeHex("0x0402"), mustDecodeHex("0x820402")},
{
[]interface{}{},
mustDecodeHex("0xc0"),
},
{
mustDecodeHex("0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"),
mustDecodeHex("0xb83cabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"),
},
{
mustDecodeHex("0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"),
mustDecodeHex("0xb8aaabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"),
},
{
[]interface{}{
mustDecodeHex("0xaaaa"),
mustDecodeHex("0xbbbb"),
mustDecodeHex("0xcccc"),
mustDecodeHex("0xdddd"),
},
mustDecodeHex("0xcc82aaaa82bbbb82cccc82dddd"),
},
{
[]interface{}{
mustDecodeHex("0xaaaaaaaaaaaaaaaaaaaa"),
mustDecodeHex("0xbbbbbbbbbbbbbbbbbbbb"),
[]interface{}{
mustDecodeHex("0xc1c1c1c1c1c1c1c1c1c1"),
mustDecodeHex("0xc2c2c2c2c2c2c2c2c2c2"),
mustDecodeHex("0xc3c3c3c3c3c3c3c3c3c3"),
},
mustDecodeHex("0xdddddddddddddddddddd"),
mustDecodeHex("0xeeeeeeeeeeeeeeeeeeee"),
mustDecodeHex("0xffffffffffffffffffff"),
},
mustDecodeHex("0xf8598aaaaaaaaaaaaaaaaaaaaa8abbbbbbbbbbbbbbbbbbbbe18ac1c1c1c1c1c1c1c1c1c18ac2c2c2c2c2c2c2c2c2c28ac3c3c3c3c3c3c3c3c3c38adddddddddddddddddddd8aeeeeeeeeeeeeeeeeeeee8affffffffffffffffffff"),
},
}
for _, tc := range testcases {
result, err := EncodeRLP(tc.Input)
require.Nil(t, err)
require.Equal(t, tc.Output.([]byte), result)
}
}
func TestDecodeString(t *testing.T) {
testcases := []TestCase{
{"0x00", "0x00"},
{"0x80", "0x"},
{"0x0f", "0x0f"},
{"0x81aa", "0xaa"},
{"0x820400", "0x0400"},
{"0xb83cabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd",
"0xabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcdabcd"},
}
for _, tc := range testcases {
input, err := hex.DecodeString(strings.Replace(tc.Input.(string), "0x", "", -1))
require.Nil(t, err)
output, err := hex.DecodeString(strings.Replace(tc.Output.(string), "0x", "", -1))
require.Nil(t, err)
result, err := DecodeRLP(input)
require.Nil(t, err)
require.Equal(t, output, result.([]byte))
}
}
func mustDecodeHex(s string) []byte {
d, err := hex.DecodeString(strings.Replace(s, "0x", "", -1))
if err != nil {
panic(fmt.Errorf("err must be nil: %w", err))
}
return d
}
func TestDecodeList(t *testing.T) {
testcases := []TestCase{
{"0xc0", []interface{}{}},
{"0xc100", []interface{}{[]byte{0}}},
{"0xc3000102", []interface{}{[]byte{0}, []byte{1}, []byte{2}}},
{"0xc4000181aa", []interface{}{[]byte{0}, []byte{1}, []byte{0xaa}}},
{"0xc6000181aa81ff", []interface{}{[]byte{0}, []byte{1}, []byte{0xaa}, []byte{0xff}}},
{"0xf8428aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd8aabcdabcdabcdabcdabcd",
[]interface{}{
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
mustDecodeHex("0xabcdabcdabcdabcdabcd"),
},
},
{"0xf1030185012a05f2008504a817c800825208942b87d1cb599bc2a606db9a0169fcec96af04ad3a880de0b6b3a764000080c0",
[]interface{}{
[]byte{3},
[]byte{1},
mustDecodeHex("0x012a05f200"),
mustDecodeHex("0x04a817c800"),
mustDecodeHex("0x5208"),
mustDecodeHex("0x2b87d1CB599Bc2a606Db9A0169fcEc96Af04ad3a"),
mustDecodeHex("0x0de0b6b3a7640000"),
[]byte{},
[]interface{}{},
}},
}
for _, tc := range testcases {
input, err := hex.DecodeString(strings.Replace(tc.Input.(string), "0x", "", -1))
require.Nil(t, err)
result, err := DecodeRLP(input)
require.Nil(t, err)
fmt.Println(result)
r := result.([]interface{})
require.Equal(t, len(tc.Output.([]interface{})), len(r))
for i, v := range r {
require.Equal(t, tc.Output.([]interface{})[i], v)
}
}
}
func TestDecodeEncodeTx(t *testing.T) {
testcases := [][]byte{
mustDecodeHex("0xdc82013a0185012a05f2008504a817c8008080872386f26fc1000000c0"),
mustDecodeHex("0xf85f82013a0185012a05f2008504a817c8008080872386f26fc1000000c001a027fa36fb9623e4d71fcdd7f7dce71eb814c9560dcf3908c1719386e2efd122fba05fb4e4227174eeb0ba84747a4fb883c8d4e0fdb129c4b1f42e90282c41480234"),
mustDecodeHex("0xf9061c82013a0185012a05f2008504a817c8008080872386f26fc10000b905bb608060405234801561001057600080fd5b506127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610556806100656000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b919061030a565b6100d6565b60405161006d9190610350565b60405180910390f35b610090600480360381019061008b9190610397565b6100f4565b60405161009d91906103f2565b60405180910390f35b6100c060048036038101906100bb919061030a565b61025f565b6040516100cd9190610350565b60405180910390f35b600060026100e38361025f565b6100ed919061043c565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101939190610496565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e891906104ca565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c9190610350565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102d7826102ac565b9050919050565b6102e7816102cc565b81146102f257600080fd5b50565b600081359050610304816102de565b92915050565b6000602082840312156103205761031f6102a7565b5b600061032e848285016102f5565b91505092915050565b6000819050919050565b61034a81610337565b82525050565b60006020820190506103656000830184610341565b92915050565b61037481610337565b811461037f57600080fd5b50565b6000813590506103918161036b565b92915050565b600080604083850312156103ae576103ad6102a7565b5b60006103bc858286016102f5565b92505060206103cd85828601610382565b9150509250929050565b60008115159050919050565b6103ec816103d7565b82525050565b600060208201905061040760008301846103e3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061044782610337565b915061045283610337565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561048b5761048a61040d565b5b828202905092915050565b60006104a182610337565b91506104ac83610337565b9250828210156104bf576104be61040d565b5b828203905092915050565b60006104d582610337565b91506104e083610337565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156105155761051461040d565b5b82820190509291505056fea26469706673582212208e5b4b874c839967f88008ed2fa42d6c2d9c9b0ae05d1d2c61faa7d229c134e664736f6c634300080d0033c080a0c4e9477f57c6848b2f1ea73a14809c1f44529d20763c947f3ac8ffd3d1629d93a011485a215457579bb13ac7b53bb9d6804763ae6fe5ce8ddd41642cea55c9a09a"),
mustDecodeHex("0xf9063082013a0185012a05f2008504a817c8008094025b594a4f1c4888cafcfaf2bb24ed95507749e0872386f26fc10000b905bb608060405234801561001057600080fd5b506127106000803273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610556806100656000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80637bd703e81461004657806390b98a1114610076578063f8b2cb4f146100a6575b600080fd5b610060600480360381019061005b919061030a565b6100d6565b60405161006d9190610350565b60405180910390f35b610090600480360381019061008b9190610397565b6100f4565b60405161009d91906103f2565b60405180910390f35b6100c060048036038101906100bb919061030a565b61025f565b6040516100cd9190610350565b60405180910390f35b600060026100e38361025f565b6100ed919061043c565b9050919050565b6000816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410156101455760009050610259565b816000803373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101939190610496565b92505081905550816000808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546101e891906104ca565b925050819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161024c9190610350565b60405180910390a3600190505b92915050565b60008060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006102d7826102ac565b9050919050565b6102e7816102cc565b81146102f257600080fd5b50565b600081359050610304816102de565b92915050565b6000602082840312156103205761031f6102a7565b5b600061032e848285016102f5565b91505092915050565b6000819050919050565b61034a81610337565b82525050565b60006020820190506103656000830184610341565b92915050565b61037481610337565b811461037f57600080fd5b50565b6000813590506103918161036b565b92915050565b600080604083850312156103ae576103ad6102a7565b5b60006103bc858286016102f5565b92505060206103cd85828601610382565b9150509250929050565b60008115159050919050565b6103ec816103d7565b82525050565b600060208201905061040760008301846103e3565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061044782610337565b915061045283610337565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561048b5761048a61040d565b5b828202905092915050565b60006104a182610337565b91506104ac83610337565b9250828210156104bf576104be61040d565b5b828203905092915050565b60006104d582610337565b91506104e083610337565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156105155761051461040d565b5b82820190509291505056fea26469706673582212208e5b4b874c839967f88008ed2fa42d6c2d9c9b0ae05d1d2c61faa7d229c134e664736f6c634300080d0033c080a0fe38720928596f9e9dfbf891d00311638efce3713f03cdd67b212ecbbcf18f29a05993e656c0b35b8a580da6aff7c89b3d3e8b1c6f83a7ce09473c0699a8500b9c"),
}
for _, tc := range testcases {
decoded, err := DecodeRLP(tc)
require.Nil(t, err)
encoded, err := EncodeRLP(decoded)
require.Nil(t, err)
require.Equal(t, tc, encoded)
}
}
func TestDecodeError(t *testing.T) {
testcases := [][]byte{
mustDecodeHex("0xdc82013a0185012a05f2008504a817c8008080872386f26fc1000000"),
mustDecodeHex("0xdc013a01012a05f2008504a817c8008080872386f26fc1000000"),
mustDecodeHex("0xdc82013a0185012a05f28504a817c08080872386f26fc1000000"),
mustDecodeHex("0xdc82013a0185012a05f504a817c080872386ffc1000000"),
mustDecodeHex("0x013a018505f2008504a817c8008080872386f26fc1000000"),
}
for _, tc := range testcases {
_, err := DecodeRLP(tc)
require.NotNil(t, err, hex.EncodeToString(tc))
}
}
func TestDecode1(t *testing.T) {
b := mustDecodeHex("0x02f8758401df5e7680832c8411832c8411830767f89452963ef50e27e06d72d59fcb4f3c2a687be3cfef880de0b6b3a764000080c080a094b11866f453ad85a980e0e8a2fc98cbaeb4409618c7734a7e12ae2f66fd405da042dbfb1b37af102023830ceeee0e703ffba0b8b3afeb8fe59f405eca9ed61072")
decoded, err := ParseEthTxArgs(b)
require.NoError(t, err)
sender, err := decoded.Sender()
require.NoError(t, err)
addr, err := address.NewFromString("f410fkkld55ioe7qg24wvt7fu6pbknb56ht7pt4zamxa")
require.NoError(t, err)
require.Equal(t, sender, addr)
}

32
chain/types/event.go Normal file
View File

@ -0,0 +1,32 @@
package types
import (
"github.com/filecoin-project/go-state-types/abi"
)
type Event struct {
// The ID of the actor that emitted this event.
Emitter abi.ActorID
// Key values making up this event.
Entries []EventEntry
}
type EventEntry struct {
// A bitmap conveying metadata or hints about this entry.
Flags uint8
// The key of this event entry
Key string
// Any DAG-CBOR encodeable type.
Value []byte
}
type FilterID [32]byte // compatible with EthHash
// EventEntry flags defined in fvm_shared
const (
EventFlagIndexedKey = 0b00000001
EventFlagIndexedValue = 0b00000010
)

View File

@ -39,6 +39,8 @@ func (kt *KeyType) UnmarshalJSON(bb []byte) error {
*kt = KTBLS
case crypto.SigTypeSecp256k1:
*kt = KTSecp256k1
case crypto.SigTypeDelegated:
*kt = KTDelegated
default:
return fmt.Errorf("unknown sigtype: %d", bst)
}
@ -51,6 +53,7 @@ const (
KTBLS KeyType = "bls"
KTSecp256k1 KeyType = "secp256k1"
KTSecp256k1Ledger KeyType = "secp256k1-ledger"
KTDelegated KeyType = "delegated"
)
// KeyInfo is used for storing keys in KeyStore

View File

@ -3,15 +3,59 @@ package types
import (
"bytes"
"github.com/ipfs/go-cid"
"github.com/filecoin-project/go-state-types/exitcode"
)
type MessageReceiptVersion byte
const (
// MessageReceiptV0 refers to pre FIP-0049 receipts.
MessageReceiptV0 MessageReceiptVersion = 0
// MessageReceiptV1 refers to post FIP-0049 receipts.
MessageReceiptV1 MessageReceiptVersion = 1
)
const EventAMTBitwidth = 5
type MessageReceipt struct {
ExitCode exitcode.ExitCode
Return []byte
GasUsed int64
version MessageReceiptVersion
ExitCode exitcode.ExitCode
Return []byte
GasUsed int64
EventsRoot *cid.Cid // Root of Event AMT with bitwidth = EventAMTBitwidth
}
// NewMessageReceiptV0 creates a new pre FIP-0049 receipt with no capability to
// convey events.
func NewMessageReceiptV0(exitcode exitcode.ExitCode, ret []byte, gasUsed int64) MessageReceipt {
return MessageReceipt{
version: MessageReceiptV0,
ExitCode: exitcode,
Return: ret,
GasUsed: gasUsed,
}
}
// NewMessageReceiptV1 creates a new pre FIP-0049 receipt with the ability to
// convey events.
func NewMessageReceiptV1(exitcode exitcode.ExitCode, ret []byte, gasUsed int64, eventsRoot *cid.Cid) MessageReceipt {
return MessageReceipt{
version: MessageReceiptV1,
ExitCode: exitcode,
Return: ret,
GasUsed: gasUsed,
EventsRoot: eventsRoot,
}
}
func (mr *MessageReceipt) Version() MessageReceiptVersion {
return mr.version
}
func (mr *MessageReceipt) Equals(o *MessageReceipt) bool {
return mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed
return mr.version == o.version && mr.ExitCode == o.ExitCode && bytes.Equal(mr.Return, o.Return) && mr.GasUsed == o.GasUsed &&
(mr.EventsRoot == o.EventsRoot || (mr.EventsRoot != nil && o.EventsRoot != nil && *mr.EventsRoot == *o.EventsRoot))
}

View File

@ -0,0 +1,359 @@
package types
import (
"fmt"
"io"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-state-types/cbor"
"github.com/filecoin-project/go-state-types/exitcode"
)
// This file contains custom CBOR serde logic to deal with the new versioned
// MessageReceipt resulting from the introduction of actor events (FIP-0049).
type messageReceiptV0 struct{ *MessageReceipt }
type messageReceiptV1 struct{ *MessageReceipt }
func (mr *MessageReceipt) MarshalCBOR(w io.Writer) error {
if mr == nil {
_, err := w.Write(cbg.CborNull)
return err
}
var m cbor.Marshaler
switch mr.version {
case MessageReceiptV0:
m = &messageReceiptV0{mr}
case MessageReceiptV1:
m = &messageReceiptV1{mr}
default:
return xerrors.Errorf("invalid message receipt version: %d", mr.version)
}
return m.MarshalCBOR(w)
}
func (mr *MessageReceipt) UnmarshalCBOR(r io.Reader) (err error) {
*mr = MessageReceipt{}
cr := cbg.NewCborReader(r)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
defer func() {
if err == io.EOF {
err = io.ErrUnexpectedEOF
}
}()
if maj != cbg.MajArray {
return fmt.Errorf("cbor input should be of type array")
}
var u cbor.Unmarshaler
switch extra {
case 3:
mr.version = MessageReceiptV0
u = &messageReceiptV0{mr}
case 4:
mr.version = MessageReceiptV1
u = &messageReceiptV1{mr}
default:
return fmt.Errorf("cbor input had wrong number of fields")
}
// Ok to pass a CBOR reader since cbg.NewCborReader will return itself when
// already a CBOR reader.
return u.UnmarshalCBOR(cr)
}
var lengthBufAMessageReceiptV0 = []byte{131}
func (t *messageReceiptV0) MarshalCBOR(w io.Writer) error {
// eliding null check since nulls were already handled in the dispatcher
cw := cbg.NewCborWriter(w)
if _, err := cw.Write(lengthBufAMessageReceiptV0); err != nil {
return err
}
// t.ExitCode (exitcode.ExitCode) (int64)
if t.ExitCode >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
return err
}
}
// t.Return ([]uint8) (slice)
if len(t.Return) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Return was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
return err
}
if _, err := cw.Write(t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
if t.GasUsed >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
return err
}
}
return nil
}
func (t *messageReceiptV0) UnmarshalCBOR(r io.Reader) (err error) {
cr := cbg.NewCborReader(r)
// t.ExitCode (exitcode.ExitCode) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.ExitCode = exitcode.ExitCode(extraI)
}
// t.Return ([]uint8) (slice)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
if extra > cbg.ByteArrayMaxLen {
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
if extra > 0 {
t.Return = make([]uint8, extra)
}
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.GasUsed = extraI
}
return nil
}
var lengthBufBMessageReceiptV1 = []byte{132}
func (t *messageReceiptV1) MarshalCBOR(w io.Writer) error {
// eliding null check since nulls were already handled in the dispatcher
cw := cbg.NewCborWriter(w)
if _, err := cw.Write(lengthBufBMessageReceiptV1); err != nil {
return err
}
// t.ExitCode (exitcode.ExitCode) (int64)
if t.ExitCode >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.ExitCode)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.ExitCode-1)); err != nil {
return err
}
}
// t.Return ([]uint8) (slice)
if len(t.Return) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Return was too long")
}
if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Return))); err != nil {
return err
}
if _, err := cw.Write(t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
if t.GasUsed >= 0 {
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.GasUsed)); err != nil {
return err
}
} else {
if err := cw.WriteMajorTypeHeader(cbg.MajNegativeInt, uint64(-t.GasUsed-1)); err != nil {
return err
}
}
// t.EventsRoot (cid.Cid) (struct)
if t.EventsRoot == nil {
if _, err := cw.Write(cbg.CborNull); err != nil {
return err
}
} else {
if err := cbg.WriteCid(cw, *t.EventsRoot); err != nil {
return xerrors.Errorf("failed to write cid field t.EventsRoot: %w", err)
}
}
return nil
}
func (t *messageReceiptV1) UnmarshalCBOR(r io.Reader) (err error) {
cr := cbg.NewCborReader(r)
// t.ExitCode (exitcode.ExitCode) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.ExitCode = exitcode.ExitCode(extraI)
}
// t.Return ([]uint8) (slice)
maj, extra, err := cr.ReadHeader()
if err != nil {
return err
}
if extra > cbg.ByteArrayMaxLen {
return fmt.Errorf("t.Return: byte array too large (%d)", extra)
}
if maj != cbg.MajByteString {
return fmt.Errorf("expected byte array")
}
if extra > 0 {
t.Return = make([]uint8, extra)
}
if _, err := io.ReadFull(cr, t.Return[:]); err != nil {
return err
}
// t.GasUsed (int64) (int64)
{
maj, extra, err := cr.ReadHeader()
var extraI int64
if err != nil {
return err
}
switch maj {
case cbg.MajUnsignedInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 positive overflow")
}
case cbg.MajNegativeInt:
extraI = int64(extra)
if extraI < 0 {
return fmt.Errorf("int64 negative oveflow")
}
extraI = -1 - extraI
default:
return fmt.Errorf("wrong type for int64 field: %d", maj)
}
t.GasUsed = extraI
}
// t.EventsRoot (cid.Cid) (struct)
{
b, err := cr.ReadByte()
if err != nil {
return err
}
if b != cbg.CborNull[0] {
if err := cr.UnreadByte(); err != nil {
return err
}
c, err := cbg.ReadCid(cr)
if err != nil {
return xerrors.Errorf("failed to read cid field t.EventsRoot: %w", err)
}
t.EventsRoot = &c
}
}
return nil
}

View File

@ -0,0 +1,75 @@
package types
import (
"bytes"
"encoding/hex"
"testing"
"github.com/ipfs/go-cid"
"github.com/stretchr/testify/assert"
)
func TestMessageReceiptSerdeRoundrip(t *testing.T) {
var (
assert = assert.New(t)
buf = new(bytes.Buffer)
err error
)
randomCid, err := cid.Decode("bafy2bzacecu7n7wbtogznrtuuvf73dsz7wasgyneqasksdblxupnyovmtwxxu")
assert.NoError(err)
//
// Version 0
//
mr := NewMessageReceiptV0(0, []byte{0x00, 0x01, 0x02, 0x04}, 42)
// marshal
err = mr.MarshalCBOR(buf)
assert.NoError(err)
t.Logf("version 0: %s\n", hex.EncodeToString(buf.Bytes()))
// unmarshal
var mr2 MessageReceipt
err = mr2.UnmarshalCBOR(buf)
assert.NoError(err)
assert.Equal(mr, mr2)
// version 0 with an events root -- should not serialize the events root!
mr.EventsRoot = &randomCid
buf.Reset()
// marshal
err = mr.MarshalCBOR(buf)
assert.NoError(err)
t.Logf("version 0 (with root): %s\n", hex.EncodeToString(buf.Bytes()))
// unmarshal
mr2 = MessageReceipt{}
err = mr2.UnmarshalCBOR(buf)
assert.NoError(err)
assert.NotEqual(mr, mr2)
assert.Nil(mr2.EventsRoot)
//
// Version 1
//
buf.Reset()
mr = NewMessageReceiptV1(0, []byte{0x00, 0x01, 0x02, 0x04}, 42, &randomCid)
// marshal
err = mr.MarshalCBOR(buf)
assert.NoError(err)
t.Logf("version 1: %s\n", hex.EncodeToString(buf.Bytes()))
// unmarshal
mr2 = MessageReceipt{}
err = mr2.UnmarshalCBOR(buf)
assert.NoError(err)
assert.Equal(mr, mr2)
assert.NotNil(mr2.EventsRoot)
}

View File

@ -196,8 +196,23 @@ func (ts *TipSet) MinTicket() *Ticket {
}
func (ts *TipSet) MinTimestamp() uint64 {
minTs := ts.Blocks()[0].Timestamp
for _, bh := range ts.Blocks()[1:] {
if ts == nil {
return 0
}
blks := ts.Blocks()
// TODO::FVM @vyzo @magik Null rounds shouldn't ever be represented as
// tipsets with no blocks; Null-round generally means that the tipset at
// that epoch doesn't exist - and the next tipset that does exist links
// straight to first epoch with blocks (@raulk agrees -- this is odd)
if len(blks) == 0 {
// null rounds make things crash -- it is threaded in every fvm instantiation
return 0
}
minTs := blks[0].Timestamp
for _, bh := range blks[1:] {
if bh.Timestamp < minTs {
minTs = bh.Timestamp
}

View File

@ -24,6 +24,8 @@ type StateTree interface {
SetActor(addr address.Address, act *Actor) error
// GetActor returns the actor from any type of `addr` provided.
GetActor(addr address.Address) (*Actor, error)
Version() StateTreeVersion
}
type storageWrapper struct {

View File

@ -19,6 +19,7 @@ import (
"github.com/filecoin-project/lotus/chain/vectors"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
)

View File

@ -24,6 +24,7 @@ import (
actorstypes "github.com/filecoin-project/go-state-types/actors"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/go-state-types/manifest"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build"
@ -275,7 +276,7 @@ func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerId address.Add
return address.Undef, gasUsed, err
}
raddr, err := ResolveToKeyAddr(stateTree, cstWithGas, info.Worker)
raddr, err := ResolveToDeterministicAddr(stateTree, cstWithGas, info.Worker)
if err != nil {
return address.Undef, gasUsed, err
}
@ -285,6 +286,7 @@ func (x *FvmExtern) workerKeyAtLookback(ctx context.Context, minerId address.Add
type FVM struct {
fvm *ffi.FVM
nv network.Version
}
func defaultFVMOpts(ctx context.Context, opts *VMOpts) (*ffi.FVMOpts, error) {
@ -309,11 +311,14 @@ func defaultFVMOpts(ctx context.Context, opts *VMOpts) (*ffi.FVMOpts, error) {
epoch: opts.Epoch,
},
Epoch: opts.Epoch,
Timestamp: opts.Timestamp,
ChainID: build.Eip155ChainId,
BaseFee: opts.BaseFee,
BaseCircSupply: circToReport,
NetworkVersion: opts.NetworkVersion,
StateBase: opts.StateBase,
Tracing: opts.Tracing || EnableDetailedTracing,
Debug: build.ActorDebugging,
}, nil
}
@ -324,20 +329,6 @@ func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
return nil, xerrors.Errorf("creating fvm opts: %w", err)
}
if os.Getenv("LOTUS_USE_FVM_CUSTOM_BUNDLE") == "1" {
av, err := actorstypes.VersionForNetwork(opts.NetworkVersion)
if err != nil {
return nil, xerrors.Errorf("mapping network version to actors version: %w", err)
}
c, ok := actors.GetManifest(av)
if !ok {
return nil, xerrors.Errorf("no manifest for custom bundle (actors version %d)", av)
}
fvmOpts.Manifest = c
}
fvm, err := ffi.CreateFVM(fvmOpts)
if err != nil {
@ -346,6 +337,7 @@ func NewFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
return &FVM{
fvm: fvm,
nv: opts.NetworkVersion,
}, nil
}
@ -448,6 +440,7 @@ func NewDebugFVM(ctx context.Context, opts *VMOpts) (*FVM, error) {
return &FVM{
fvm: fvm,
nv: opts.NetworkVersion,
}, nil
}
@ -466,10 +459,12 @@ func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet
}
duration := time.Since(start)
receipt := types.MessageReceipt{
Return: ret.Return,
ExitCode: exitcode.ExitCode(ret.ExitCode),
GasUsed: ret.GasUsed,
var receipt types.MessageReceipt
if vm.nv >= network.Version18 {
receipt = types.NewMessageReceiptV1(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed, ret.EventsRoot)
} else {
receipt = types.NewMessageReceiptV0(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed)
}
var aerr aerrors.ActorError
@ -530,10 +525,12 @@ func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (*
}
duration := time.Since(start)
receipt := types.MessageReceipt{
Return: ret.Return,
ExitCode: exitcode.ExitCode(ret.ExitCode),
GasUsed: ret.GasUsed,
var receipt types.MessageReceipt
if vm.nv >= network.Version18 {
receipt = types.NewMessageReceiptV1(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed, ret.EventsRoot)
} else {
receipt = types.NewMessageReceiptV0(exitcode.ExitCode(ret.ExitCode), ret.Return, ret.GasUsed)
}
var aerr aerrors.ActorError

View File

@ -111,6 +111,7 @@ var Prices = map[abi.ChainEpoch]Pricelist{
verifySignature: map[crypto.SigType]int64{
crypto.SigTypeBLS: 16598605,
crypto.SigTypeSecp256k1: 1637292,
crypto.SigTypeDelegated: 1637292,
},
hashingBase: 31355,

View File

@ -284,16 +284,16 @@ func DecodeParams(b []byte, out interface{}) error {
}
func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{}, error) {
if builtin.IsAccountActor(act.Code) { // Account code special case
return nil, nil
}
actInfo, ok := i.actors[act.Code]
if !ok {
return nil, xerrors.Errorf("state type for actor %s not found", act.Code)
}
um := actInfo.vmActor.State()
if um == nil {
// TODO::FVM @arajasek I would like to assert that we have the empty object here
return nil, nil
}
if err := um.UnmarshalCBOR(bytes.NewReader(b)); err != nil {
return nil, xerrors.Errorf("unmarshaling actor state: %w", err)
}

View File

@ -168,8 +168,8 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act
aerr = ar
return
}
//log.Desugar().WithOptions(zap.AddStacktrace(zapcore.ErrorLevel)).
//Sugar().Errorf("spec actors failure: %s", r)
// log.Desugar().WithOptions(zap.AddStacktrace(zapcore.ErrorLevel)).
// Sugar().Errorf("spec actors failure: %s", r)
log.Errorf("spec actors failure: %s", r)
if rt.NetworkVersion() <= network.Version3 {
aerr = aerrors.Newf(1, "spec actors failure: %s", r)
@ -249,7 +249,7 @@ func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparati
func (rt *Runtime) NewActorAddress() address.Address {
var b bytes.Buffer
oa, _ := ResolveToKeyAddr(rt.vm.cstate, rt.vm.cst, rt.origin)
oa, _ := ResolveToDeterministicAddr(rt.vm.cstate, rt.vm.cst, rt.origin)
if err := oa.MarshalCBOR(&b); err != nil { // todo: spec says cbor; why not just bytes?
panic(aerrors.Fatalf("writing caller address into a buffer: %v", err))
}

View File

@ -255,7 +255,7 @@ func (ss *syscallShim) workerKeyAtLookback(height abi.ChainEpoch) (address.Addre
return address.Undef, err
}
return ResolveToKeyAddr(ss.cstate, ss.cst, info.Worker)
return ResolveToDeterministicAddr(ss.cstate, ss.cst, info.Worker)
}
func (ss *syscallShim) VerifyPoSt(info proof7.WindowPoStVerifyInfo) error {
@ -270,8 +270,8 @@ func (ss *syscallShim) VerifyPoSt(info proof7.WindowPoStVerifyInfo) error {
}
func (ss *syscallShim) VerifySeal(info proof7.SealVerifyInfo) error {
//_, span := trace.StartSpan(ctx, "ValidatePoRep")
//defer span.End()
// _, span := trace.StartSpan(ctx, "ValidatePoRep")
// defer span.End()
miner, err := address.NewIDAddress(uint64(info.Miner))
if err != nil {
@ -284,7 +284,7 @@ func (ss *syscallShim) VerifySeal(info proof7.SealVerifyInfo) error {
log.Debugf("Verif r:%s; d:%s; m:%s; t:%x; s:%x; N:%d; p:%x", info.SealedCID, info.UnsealedCID, miner, ticket, seed, info.SectorID.Number, proof)
//func(ctx context.Context, maddr address.Address, ssize abi.SectorSize, commD, commR, ticket, proof, seed []byte, sectorID abi.SectorNumber)
// func(ctx context.Context, maddr address.Address, ssize abi.SectorSize, commD, commR, ticket, proof, seed []byte, sectorID abi.SectorNumber)
ok, err := ss.verifier.VerifySeal(info)
if err != nil {
return xerrors.Errorf("failed to validate PoRep: %w", err)
@ -325,7 +325,7 @@ func (ss *syscallShim) VerifyReplicaUpdate(update proof7.ReplicaUpdateInfo) erro
func (ss *syscallShim) VerifySignature(sig crypto.Signature, addr address.Address, input []byte) error {
// TODO: in genesis setup, we are currently faking signatures
kaddr, err := ResolveToKeyAddr(ss.cstate, ss.cst, addr)
kaddr, err := ResolveToDeterministicAddr(ss.cstate, ss.cst, addr)
if err != nil {
return err
}

View File

@ -45,9 +45,11 @@ var (
gasOnActorExec = newGasCharge("OnActorExec", 0, 0)
)
// ResolveToKeyAddr returns the public key type of address (`BLS`/`SECP256K1`) of an account actor identified by `addr`.
func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Address) (address.Address, error) {
if addr.Protocol() == address.BLS || addr.Protocol() == address.SECP256K1 {
// ResolveToDeterministicAddr returns the public key type of address
// (`BLS`/`SECP256K1`) of an actor identified by `addr`, or its
// delegated address.
func ResolveToDeterministicAddr(state types.StateTree, cst cbor.IpldStore, addr address.Address) (address.Address, error) {
if addr.Protocol() == address.BLS || addr.Protocol() == address.SECP256K1 || addr.Protocol() == address.Delegated {
return addr, nil
}
@ -56,12 +58,19 @@ func ResolveToKeyAddr(state types.StateTree, cst cbor.IpldStore, addr address.Ad
return address.Undef, xerrors.Errorf("failed to find actor: %s", addr)
}
if state.Version() >= types.StateTreeVersion5 {
if act.Address != nil {
// If there _is_ an f4 address, return it as "key" address
return *act.Address, nil
}
}
aast, err := account.Load(adt.WrapStore(context.TODO(), cst), act)
if err != nil {
return address.Undef, xerrors.Errorf("failed to get account actor state for %s: %w", addr, err)
}
return aast.PubkeyAddress()
}
var (
@ -216,6 +225,7 @@ type LegacyVM struct {
type VMOpts struct {
StateBase cid.Cid
Epoch abi.ChainEpoch
Timestamp uint64
Rand Rand
Bstore blockstore.Blockstore
Actors *ActorRegistry

View File

@ -7,6 +7,7 @@ import (
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/lib/sigs"
)
@ -50,6 +51,22 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
if err != nil {
return nil, xerrors.Errorf("converting Secp256k1 to address: %w", err)
}
case types.KTDelegated:
// Transitory Delegated signature verification as per FIP-0055
ethAddr, err := ethtypes.EthAddressFromPubKey(k.PublicKey)
if err != nil {
return nil, xerrors.Errorf("failed to calculate Eth address from public key: %w", err)
}
ea, err := ethtypes.CastEthAddress(ethAddr)
if err != nil {
return nil, xerrors.Errorf("failed to create ethereum address from bytes: %w", err)
}
k.Address, err = ea.ToFilecoinAddress()
if err != nil {
return nil, xerrors.Errorf("converting Delegated to address: %w", err)
}
case types.KTBLS:
k.Address, err = address.NewBLSAddress(k.PublicKey)
if err != nil {
@ -58,6 +75,7 @@ func NewKey(keyinfo types.KeyInfo) (*Key, error) {
default:
return nil, xerrors.Errorf("unsupported key type: %s", k.Type)
}
return k, nil
}
@ -68,6 +86,8 @@ func ActSigType(typ types.KeyType) crypto.SigType {
return crypto.SigTypeBLS
case types.KTSecp256k1:
return crypto.SigTypeSecp256k1
case types.KTDelegated:
return crypto.SigTypeDelegated
default:
return crypto.SigTypeUnknown
}

View File

@ -16,7 +16,8 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet/key"
"github.com/filecoin-project/lotus/lib/sigs"
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures
)

View File

@ -149,7 +149,7 @@ var ChainGetBlock = &cli.Command{
recpts, err := api.ChainGetParentReceipts(ctx, bcid)
if err != nil {
log.Warn(err)
//return xerrors.Errorf("failed to get receipts: %w", err)
// return xerrors.Errorf("failed to get receipts: %w", err)
}
cblock := struct {

View File

@ -81,6 +81,7 @@ var Commands = []*cli.Command{
WithCategory("developer", LogCmd),
WithCategory("developer", WaitApiCmd),
WithCategory("developer", FetchParamCmd),
WithCategory("developer", EvmCmd),
WithCategory("network", NetCmd),
WithCategory("network", SyncCmd),
WithCategory("status", StatusCmd),

496
cli/evm.go Normal file
View File

@ -0,0 +1,496 @@
package cli
import (
"bytes"
"context"
"encoding/base64"
"encoding/hex"
"fmt"
"os"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
amt4 "github.com/filecoin-project/go-amt-ipld/v4"
"github.com/filecoin-project/go-state-types/abi"
"github.com/filecoin-project/go-state-types/big"
builtintypes "github.com/filecoin-project/go-state-types/builtin"
"github.com/filecoin-project/go-state-types/builtin/v10/eam"
"github.com/filecoin-project/lotus/api/v0api"
"github.com/filecoin-project/lotus/chain/actors"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
)
var EvmCmd = &cli.Command{
Name: "evm",
Usage: "Commands related to the Filecoin EVM runtime",
Subcommands: []*cli.Command{
EvmDeployCmd,
EvmInvokeCmd,
EvmGetInfoCmd,
EvmCallSimulateCmd,
EvmGetContractAddress,
},
}
var EvmGetInfoCmd = &cli.Command{
Name: "stat",
Usage: "Print eth/filecoin addrs and code cid",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "filAddr",
Usage: "Filecoin address",
},
&cli.StringFlag{
Name: "ethAddr",
Usage: "Ethereum address",
},
},
Action: func(cctx *cli.Context) error {
filAddr := cctx.String("filAddr")
ethAddr := cctx.String("ethAddr")
var faddr address.Address
var eaddr ethtypes.EthAddress
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if filAddr != "" {
addr, err := address.NewFromString(filAddr)
if err != nil {
return err
}
eaddr, faddr, err = ethAddrFromFilecoinAddress(ctx, addr, api)
if err != nil {
return err
}
} else if ethAddr != "" {
eaddr, err = ethtypes.ParseEthAddress(ethAddr)
if err != nil {
return err
}
faddr, err = eaddr.ToFilecoinAddress()
if err != nil {
return err
}
} else {
return xerrors.Errorf("Neither filAddr nor ethAddr specified")
}
actor, err := api.StateGetActor(ctx, faddr, types.EmptyTSK)
if err != nil {
return err
}
fmt.Println("Filecoin address: ", faddr)
fmt.Println("Eth address: ", eaddr)
fmt.Println("Code cid: ", actor.Code.String())
return nil
},
}
var EvmCallSimulateCmd = &cli.Command{
Name: "call",
Usage: "Simulate an eth contract call",
ArgsUsage: "[from] [to] [params]",
Action: func(cctx *cli.Context) error {
if cctx.NArg() != 3 {
return IncorrectNumArgs(cctx)
}
fromEthAddr, err := ethtypes.ParseEthAddress(cctx.Args().Get(0))
if err != nil {
return err
}
toEthAddr, err := ethtypes.ParseEthAddress(cctx.Args().Get(1))
if err != nil {
return err
}
params, err := hex.DecodeString(cctx.Args().Get(2))
if err != nil {
return err
}
api, closer, err := GetFullNodeAPIV1(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
res, err := api.EthCall(ctx, ethtypes.EthCall{
From: &fromEthAddr,
To: &toEthAddr,
Data: params,
}, "")
if err != nil {
fmt.Println("Eth call fails, return val: ", res)
return err
}
fmt.Println("Result: ", res)
return nil
},
}
var EvmGetContractAddress = &cli.Command{
Name: "contract-address",
Usage: "Generate contract address from smart contract code",
ArgsUsage: "[senderEthAddr] [salt] [contractHexPath]",
Action: func(cctx *cli.Context) error {
if cctx.NArg() != 3 {
return IncorrectNumArgs(cctx)
}
sender, err := ethtypes.ParseEthAddress(cctx.Args().Get(0))
if err != nil {
return err
}
salt, err := hex.DecodeString(cctx.Args().Get(1))
if err != nil {
return xerrors.Errorf("Could not decode salt: %w", err)
}
if len(salt) > 32 {
return xerrors.Errorf("Len of salt bytes greater than 32")
}
var fsalt [32]byte
copy(fsalt[:], salt[:])
contractBin := cctx.Args().Get(2)
if err != nil {
return err
}
contractHex, err := os.ReadFile(contractBin)
if err != nil {
return err
}
contract, err := hex.DecodeString(string(contractHex))
if err != nil {
return xerrors.Errorf("Could not decode contract file: %w", err)
}
contractAddr, err := ethtypes.GetContractEthAddressFromCode(sender, fsalt, contract)
if err != nil {
return err
}
fmt.Println("Contract Eth address: ", contractAddr)
return nil
},
}
var EvmDeployCmd = &cli.Command{
Name: "deploy",
Usage: "Deploy an EVM smart contract and return its address",
ArgsUsage: "contract",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "optionally specify the account to use for sending the creation message",
},
&cli.BoolFlag{
Name: "hex",
Usage: "use when input contract is in hex",
},
},
Action: func(cctx *cli.Context) error {
afmt := NewAppFmt(cctx.App)
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if argc := cctx.Args().Len(); argc != 1 {
return xerrors.Errorf("must pass the contract init code")
}
contract, err := os.ReadFile(cctx.Args().First())
if err != nil {
return xerrors.Errorf("failed to read contract: %w", err)
}
if cctx.Bool("hex") {
contract, err = hex.DecodeString(string(contract))
if err != nil {
return xerrors.Errorf("failed to decode contract: %w", err)
}
}
var fromAddr address.Address
if from := cctx.String("from"); from == "" {
fromAddr, err = api.WalletDefaultAddress(ctx)
} else {
fromAddr, err = address.NewFromString(from)
}
if err != nil {
return err
}
initcode := abi.CborBytes(contract)
params, err := actors.SerializeParams(&initcode)
if err != nil {
return fmt.Errorf("failed to serialize Create params: %w", err)
}
msg := &types.Message{
To: builtintypes.EthereumAddressManagerActorAddr,
From: fromAddr,
Value: big.Zero(),
Method: builtintypes.MethodsEAM.CreateExternal,
Params: params,
}
// TODO: On Jan 11th, we decided to add an `EAM#create_external` method
// that uses the nonce of the caller instead of taking a user-supplied nonce.
// Track: https://github.com/filecoin-project/ref-fvm/issues/1255
// When that's implemented, we should migrate the CLI to use that,
// as `EAM#create` will be reserved for the EVM runtime actor.
// TODO: this is very racy. It may assign a _different_ nonce than the expected one.
afmt.Println("sending message...")
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return xerrors.Errorf("failed to push message: %w", err)
}
afmt.Println("waiting for message to execute...")
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
if err != nil {
return xerrors.Errorf("error waiting for message: %w", err)
}
// check it executed successfully
if wait.Receipt.ExitCode != 0 {
return xerrors.Errorf("actor execution failed")
}
var result eam.CreateReturn
r := bytes.NewReader(wait.Receipt.Return)
if err := result.UnmarshalCBOR(r); err != nil {
return xerrors.Errorf("error unmarshaling return value: %w", err)
}
addr, err := address.NewIDAddress(result.ActorID)
if err != nil {
return err
}
afmt.Printf("Actor ID: %d\n", result.ActorID)
afmt.Printf("ID Address: %s\n", addr)
afmt.Printf("Robust Address: %s\n", result.RobustAddress)
afmt.Printf("Eth Address: %s\n", "0x"+hex.EncodeToString(result.EthAddress[:]))
ea, err := ethtypes.CastEthAddress(result.EthAddress[:])
if err != nil {
return fmt.Errorf("failed to create ethereum address: %w", err)
}
delegated, err := ea.ToFilecoinAddress()
if err != nil {
return fmt.Errorf("failed to calculate f4 address: %w", err)
}
afmt.Printf("f4 Address: %s\n", delegated)
if len(wait.Receipt.Return) > 0 {
result := base64.StdEncoding.EncodeToString(wait.Receipt.Return)
afmt.Printf("Return: %s\n", result)
}
return nil
},
}
var EvmInvokeCmd = &cli.Command{
Name: "invoke",
Usage: "Invoke an EVM smart contract using the specified CALLDATA",
ArgsUsage: "address calldata",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "optionally specify the account to use for sending the exec message",
}, &cli.IntFlag{
Name: "value",
Usage: "optionally specify the value to be sent with the invokation message",
},
},
Action: func(cctx *cli.Context) error {
afmt := NewAppFmt(cctx.App)
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := ReqContext(cctx)
if argc := cctx.Args().Len(); argc < 2 || argc > 3 {
return xerrors.Errorf("must pass the address, entry point and (optionally) input data")
}
addr, err := address.NewFromString(cctx.Args().Get(0))
if err != nil {
return xerrors.Errorf("failed to decode address: %w", err)
}
var calldata []byte
calldata, err = hex.DecodeString(cctx.Args().Get(2))
if err != nil {
return xerrors.Errorf("decoding hex input data: %w", err)
}
var buffer bytes.Buffer
if err := cbg.WriteByteArray(&buffer, calldata); err != nil {
return xerrors.Errorf("failed to encode evm params as cbor: %w", err)
}
calldata = buffer.Bytes()
var fromAddr address.Address
if from := cctx.String("from"); from == "" {
defaddr, err := api.WalletDefaultAddress(ctx)
if err != nil {
return err
}
fromAddr = defaddr
} else {
addr, err := address.NewFromString(from)
if err != nil {
return err
}
fromAddr = addr
}
val := abi.NewTokenAmount(cctx.Int64("value"))
msg := &types.Message{
To: addr,
From: fromAddr,
Value: val,
Method: abi.MethodNum(2),
Params: calldata,
}
afmt.Println("sending message...")
smsg, err := api.MpoolPushMessage(ctx, msg, nil)
if err != nil {
return xerrors.Errorf("failed to push message: %w", err)
}
afmt.Println("waiting for message to execute...")
wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0)
if err != nil {
return xerrors.Errorf("error waiting for message: %w", err)
}
// check it executed successfully
if wait.Receipt.ExitCode != 0 {
return xerrors.Errorf("actor execution failed")
}
afmt.Println("Gas used: ", wait.Receipt.GasUsed)
result, err := cbg.ReadByteArray(bytes.NewBuffer(wait.Receipt.Return), uint64(len(wait.Receipt.Return)))
if err != nil {
return xerrors.Errorf("evm result not correctly encoded: %w", err)
}
if len(result) > 0 {
afmt.Println(hex.EncodeToString(result))
} else {
afmt.Println("OK")
}
if eventsRoot := wait.Receipt.EventsRoot; eventsRoot != nil {
afmt.Println("Events emitted:")
s := &apiIpldStore{ctx, api}
amt, err := amt4.LoadAMT(ctx, s, *eventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth))
if err != nil {
return err
}
var evt types.Event
err = amt.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error {
fmt.Printf("%x\n", deferred.Raw)
if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil {
return err
}
if err != nil {
return err
}
fmt.Printf("\tEmitter ID: %s\n", evt.Emitter)
for _, e := range evt.Entries {
value, err := cbg.ReadByteArray(bytes.NewBuffer(e.Value), uint64(len(e.Value)))
if err != nil {
return err
}
fmt.Printf("\t\tKey: %s, Value: 0x%x, Flags: b%b\n", e.Key, value, e.Flags)
}
return nil
})
}
if err != nil {
return err
}
return nil
},
}
func ethAddrFromFilecoinAddress(ctx context.Context, addr address.Address, fnapi v0api.FullNode) (ethtypes.EthAddress, address.Address, error) {
var faddr address.Address
var err error
switch addr.Protocol() {
case address.BLS, address.SECP256K1:
faddr, err = fnapi.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
case address.Actor, address.ID:
faddr, err = fnapi.StateLookupID(ctx, addr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
fAct, err := fnapi.StateGetActor(ctx, faddr, types.EmptyTSK)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
if fAct.Address != nil && (*fAct.Address).Protocol() == address.Delegated {
faddr = *fAct.Address
}
case address.Delegated:
faddr = addr
default:
return ethtypes.EthAddress{}, addr, xerrors.Errorf("Filecoin address doesn't match known protocols")
}
ethAddr, err := ethtypes.EthAddressFromFilecoinAddress(faddr)
if err != nil {
return ethtypes.EthAddress{}, addr, err
}
return ethAddr, faddr, nil
}

View File

@ -776,6 +776,7 @@ var StateGetActorCmd = &cli.Command{
fmt.Printf("Nonce:\t\t%d\n", a.Nonce)
fmt.Printf("Code:\t\t%s (%s)\n", a.Code, strtype)
fmt.Printf("Head:\t\t%s\n", a.Head)
fmt.Printf("Delegated address:\t\t%s\n", a.Address)
return nil
},

View File

@ -42,6 +42,7 @@ import (
"github.com/filecoin-project/lotus/chain/vm"
lcli "github.com/filecoin-project/lotus/cli"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/filecoin-project/lotus/node/repo"
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"

View File

@ -10,6 +10,7 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
)

View File

@ -23,6 +23,7 @@ import (
"github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/chain/wallet/key"
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
"github.com/filecoin-project/lotus/node/modules"
"github.com/filecoin-project/lotus/node/modules/lp2p"

View File

@ -4,10 +4,10 @@ import (
"context"
"fmt"
"io"
"strconv"
"time"
"github.com/ipfs/go-cid"
logging "github.com/ipfs/go-log/v2"
"github.com/urfave/cli/v2"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors"
@ -25,6 +25,8 @@ import (
adt9 "github.com/filecoin-project/go-state-types/builtin/v9/util/adt"
verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg"
"github.com/filecoin-project/go-state-types/manifest"
mutil "github.com/filecoin-project/go-state-types/migration"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/specs-actors/v7/actors/migration/nv15"
"github.com/filecoin-project/lotus/blockstore"
@ -48,9 +50,9 @@ import (
)
var migrationsCmd = &cli.Command{
Name: "migrate-nv17",
Description: "Run the nv17 migration",
ArgsUsage: "[block to look back from]",
Name: "migrate-state",
Description: "Run a network upgrade migration",
ArgsUsage: "[new network version, block to look back from]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
@ -66,16 +68,21 @@ var migrationsCmd = &cli.Command{
Action: func(cctx *cli.Context) error {
ctx := context.TODO()
err := logging.SetLogLevelRegex("badger*", "ERROR")
if cctx.NArg() != 2 {
return lcli.IncorrectNumArgs(cctx)
}
nv, err := strconv.ParseUint(cctx.Args().Get(0), 10, 32)
if err != nil {
return fmt.Errorf("failed to parse network version: %w", err)
}
upgradeActorsFunc, preUpgradeActorsFunc, checkInvariantsFunc, err := getMigrationFuncsForNetwork(network.Version(nv))
if err != nil {
return err
}
if cctx.NArg() != 1 {
return lcli.IncorrectNumArgs(cctx)
}
blkCid, err := cid.Decode(cctx.Args().First())
blkCid, err := cid.Decode(cctx.Args().Get(1))
if err != nil {
return fmt.Errorf("failed to parse input: %w", err)
}
@ -130,7 +137,7 @@ var migrationsCmd = &cli.Command{
startTime := time.Now()
newCid2, err := filcns.UpgradeActorsV9(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
newCid2, err := upgradeActorsFunc(ctx, sm, nv15.NewMemMigrationCache(), nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
if err != nil {
return err
}
@ -143,7 +150,7 @@ var migrationsCmd = &cli.Command{
fmt.Println("completed round actual (without cache), took ", uncachedMigrationTime)
if !cctx.IsSet("skip-pre-migration") {
cache := nv15.NewMemMigrationCache()
cache := mutil.NewMemMigrationCache()
ts1, err := cs.GetTipsetByHeight(ctx, blk.Height-240, migrationTs, false)
if err != nil {
@ -152,7 +159,7 @@ var migrationsCmd = &cli.Command{
startTime = time.Now()
err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1)
err = preUpgradeActorsFunc(ctx, sm, cache, ts1.ParentState(), ts1.Height()-1, ts1)
if err != nil {
return err
}
@ -166,7 +173,7 @@ var migrationsCmd = &cli.Command{
startTime = time.Now()
err = filcns.PreUpgradeActorsV9(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2)
err = preUpgradeActorsFunc(ctx, sm, cache, ts2.ParentState(), ts2.Height()-1, ts2)
if err != nil {
return err
}
@ -175,7 +182,7 @@ var migrationsCmd = &cli.Command{
startTime = time.Now()
newCid1, err := filcns.UpgradeActorsV9(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
newCid1, err := upgradeActorsFunc(ctx, sm, cache, nil, blk.ParentStateRoot, blk.Height-1, migrationTs)
if err != nil {
return err
}
@ -192,7 +199,10 @@ var migrationsCmd = &cli.Command{
}
if cctx.Bool("check-invariants") {
err = checkMigrationInvariants(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1)
if checkInvariantsFunc == nil {
return xerrors.Errorf("check invariants not implemented for nv%d", nv)
}
err = checkInvariantsFunc(ctx, blk.ParentStateRoot, newCid2, bs, blk.Height-1)
if err != nil {
return err
}
@ -202,7 +212,22 @@ var migrationsCmd = &cli.Command{
},
}
func checkMigrationInvariants(ctx context.Context, v8StateRootCid cid.Cid, v9StateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
func getMigrationFuncsForNetwork(nv network.Version) (UpgradeActorsFunc, PreUpgradeActorsFunc, CheckInvariantsFunc, error) {
switch nv {
case network.Version17:
return filcns.UpgradeActorsV9, filcns.PreUpgradeActorsV9, checkNv17Invariants, nil
case network.Version18:
return filcns.UpgradeActorsV10, filcns.PreUpgradeActorsV10, nil, nil
default:
return nil, nil, nil, xerrors.Errorf("migration not implemented for nv%d", nv)
}
}
type UpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.MigrationCache, stmgr.ExecMonitor, cid.Cid, abi.ChainEpoch, *types.TipSet) (cid.Cid, error)
type PreUpgradeActorsFunc = func(context.Context, *stmgr.StateManager, stmgr.MigrationCache, cid.Cid, abi.ChainEpoch, *types.TipSet) error
type CheckInvariantsFunc = func(context.Context, cid.Cid, cid.Cid, blockstore.Blockstore, abi.ChainEpoch) error
func checkNv17Invariants(ctx context.Context, v8StateRootCid cid.Cid, v9StateRootCid cid.Cid, bs blockstore.Blockstore, epoch abi.ChainEpoch) error {
actorStore := store.ActorStore(ctx, bs)
startTime := time.Now()

View File

@ -74,14 +74,17 @@ func (sim *Simulation) makeTipSet(ctx context.Context, messages []*types.Message
Timestamp: uts,
ElectionProof: &types.ElectionProof{WinCount: 1},
}}
err = sim.Node.Chainstore.PersistBlockHeaders(ctx, blks...)
if err != nil {
return nil, xerrors.Errorf("failed to persist block headers: %w", err)
}
newTipSet, err := types.NewTipSet(blks)
if err != nil {
return nil, xerrors.Errorf("failed to create new tipset: %w", err)
}
err = sim.Node.Chainstore.PersistTipset(ctx, newTipSet)
if err != nil {
return nil, xerrors.Errorf("failed to persist block headers: %w", err)
}
now := time.Now()
_, _, err = sim.StateManager.TipSetState(ctx, newTipSet)
if err != nil {

View File

@ -28,7 +28,8 @@ import (
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/conformance/chaos"
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
_ "github.com/filecoin-project/lotus/lib/sigs/bls" // enable bls signatures
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
_ "github.com/filecoin-project/lotus/lib/sigs/secp" // enable secp signatures
"github.com/filecoin-project/lotus/storage/sealer/ffiwrapper"
)

View File

@ -464,7 +464,9 @@ Inputs:
{
"SealProof": 8,
"SectorNumber": 9,
"SectorKey": null,
"SectorKey": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"SealedCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
@ -1279,8 +1281,12 @@ Response:
"ProposalCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"AddFundsCid": null,
"PublishCid": null,
"AddFundsCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PublishCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Miner": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"Client": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"State": 42,
@ -1295,7 +1301,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -1457,8 +1465,12 @@ Response:
"ProposalCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"AddFundsCid": null,
"PublishCid": null,
"AddFundsCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PublishCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Miner": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"Client": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"State": 42,
@ -1473,7 +1485,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -1509,7 +1523,9 @@ Response:
"Selector": {
"Raw": "Ynl0ZSBhcnJheQ=="
},
"PieceCID": null,
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PricePerByte": "0",
"PaymentInterval": 42,
"PaymentIntervalIncrease": 42,
@ -2908,7 +2924,9 @@ Inputs:
1024,
{},
{
"PublishCid": null,
"PublishCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"DealID": 5432,
"DealProposal": {
"PieceCID": {
@ -2962,7 +2980,9 @@ Response:
"FailedSectors": {
"123": "can't acquire read lock"
},
"Msg": null,
"Msg": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Error": "string value"
}
]
@ -3156,7 +3176,9 @@ Response:
123,
124
],
"Msg": null,
"Msg": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Error": "string value"
}
]
@ -3204,7 +3226,9 @@ Inputs:
}
},
"DealInfo": {
"PublishCid": null,
"PublishCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"DealID": 5432,
"DealProposal": {
"PieceCID": {
@ -3232,8 +3256,12 @@ Inputs:
"TicketValue": "Bw==",
"TicketEpoch": 10101,
"PreCommit1Out": "Bw==",
"CommD": null,
"CommR": null,
"CommD": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"CommR": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PreCommitInfo": {
"SealProof": 8,
"SectorNumber": 9,
@ -3245,10 +3273,14 @@ Inputs:
5432
],
"Expiration": 10101,
"UnsealedCid": null
"UnsealedCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"PreCommitDeposit": "0",
"PreCommitMessage": null,
"PreCommitMessage": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PreCommitTipSet": [
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
@ -3260,7 +3292,9 @@ Inputs:
"SeedValue": "Bw==",
"SeedEpoch": 10101,
"CommitProof": "Ynl0ZSBhcnJheQ==",
"CommitMessage": null,
"CommitMessage": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Log": [
{
"Kind": "string value",
@ -3396,7 +3430,12 @@ Perms: admin
Inputs: `null`
Response: `null`
Response:
```json
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
```
### SectorTerminatePending
SectorTerminatePending returns a list of pending sector terminations to be sent in the next batch message
@ -3497,8 +3536,12 @@ Response:
{
"SectorID": 9,
"State": "Proving",
"CommD": null,
"CommR": null,
"CommD": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"CommR": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Proof": "Ynl0ZSBhcnJheQ==",
"Deals": [
5432
@ -3512,7 +3555,9 @@ Response:
}
},
"DealInfo": {
"PublishCid": null,
"PublishCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"DealID": 5432,
"DealProposal": {
"PieceCID": {
@ -3545,11 +3590,17 @@ Response:
"Value": "Bw==",
"Epoch": 10101
},
"PreCommitMsg": null,
"CommitMsg": null,
"PreCommitMsg": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"CommitMsg": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Retries": 42,
"ToUpgrade": true,
"ReplicaUpdateMessage": null,
"ReplicaUpdateMessage": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"LastErr": "string value",
"Log": [
{
@ -3603,7 +3654,9 @@ Inputs:
1040384,
1024,
"Bw==",
null
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
]
```

View File

@ -754,7 +754,10 @@ Response:
{
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
]
```
@ -1247,7 +1250,9 @@ Inputs:
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
null
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
]
```
@ -1259,7 +1264,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Piece": null,
"Piece": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Size": 42,
"MinPrice": "0",
"UnsealPrice": "0",
@ -1270,7 +1277,9 @@ Response:
"MinerPeer": {
"Address": "f01234",
"ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"PieceCID": null
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
}
]
@ -1341,7 +1350,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -1445,7 +1456,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -1510,7 +1523,9 @@ Response:
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"ID": 5,
"PieceCID": null,
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PricePerByte": "0",
"UnsealPrice": "0",
"Status": 0,
@ -1683,7 +1698,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -1748,7 +1765,9 @@ Response:
{
"Key": 50,
"Err": "string value",
"Root": null,
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Source": "string value",
"FilePath": "string value",
"CARPath": "string value"
@ -1773,7 +1792,9 @@ Response:
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"ID": 5,
"PieceCID": null,
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PricePerByte": "0",
"UnsealPrice": "0",
"Status": 0,
@ -1834,7 +1855,9 @@ Inputs:
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
null
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
]
```
@ -1845,7 +1868,9 @@ Response:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Piece": null,
"Piece": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Size": 42,
"MinPrice": "0",
"UnsealPrice": "0",
@ -1856,7 +1881,9 @@ Response:
"MinerPeer": {
"Address": "f01234",
"ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"PieceCID": null
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
}
```
@ -1933,7 +1960,9 @@ Inputs:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Piece": null,
"Piece": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"DatamodelPathSelector": "Links/21/Hash/Links/42/Hash",
"Size": 42,
"FromLocalCAR": "string value",
@ -1946,7 +1975,9 @@ Inputs:
"MinerPeer": {
"Address": "f01234",
"ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"PieceCID": null
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
},
{
@ -1988,7 +2019,9 @@ Inputs:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"Piece": null,
"Piece": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"DatamodelPathSelector": "Links/21/Hash/Links/42/Hash",
"Size": 42,
"FromLocalCAR": "string value",
@ -2001,7 +2034,9 @@ Inputs:
"MinerPeer": {
"Address": "f01234",
"ID": "12D3KooWGzxzKZYveHXtpG6AsrUJBcWxHBFS2HsEoGTxrMLvKXtf",
"PieceCID": null
"PieceCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
},
{
@ -2037,7 +2072,9 @@ Inputs:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -2053,7 +2090,12 @@ Inputs:
]
```
Response: `null`
Response:
```json
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
```
### ClientStatelessDeal
ClientStatelessDeal fire-and-forget-proposes an offline deal to a miner without subsequent tracking.
@ -2070,7 +2112,9 @@ Inputs:
"Root": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceCid": null,
"PieceCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"PieceSize": 1024,
"RawBlockSize": 42
},
@ -2086,7 +2130,12 @@ Inputs:
]
```
Response: `null`
Response:
```json
{
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
```
## Create
@ -2613,7 +2662,9 @@ Response:
{
"SealProof": 8,
"SectorNumber": 9,
"SectorKey": null,
"SectorKey": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"SealedCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
@ -4156,7 +4207,9 @@ Response:
"PendingAmt": "0",
"NonReservedAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"PendingWaitSentinel": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
}
@ -4185,7 +4238,9 @@ Response:
"PendingAmt": "0",
"NonReservedAmt": "0",
"PendingAvailableAmt": "0",
"PendingWaitSentinel": null,
"PendingWaitSentinel": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"QueuedAmt": "0",
"VoucherReedeemedAmt": "0"
}
@ -4792,7 +4847,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"GasCost": {
"Message": {
@ -4825,7 +4883,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -4869,7 +4930,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -5059,7 +5123,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"GasCost": {
"Message": {
@ -5092,7 +5159,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -5136,7 +5206,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -5460,7 +5533,8 @@ Response:
"UpgradeChocolateHeight": 10101,
"UpgradeOhSnapHeight": 10101,
"UpgradeSkyrHeight": 10101,
"UpgradeSharkHeight": 10101
"UpgradeSharkHeight": 10101,
"UpgradeHyggeHeight": 10101
}
}
```
@ -5551,7 +5625,10 @@ Response:
{
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
}
```
@ -5864,7 +5941,9 @@ Response:
"ExpectedStoragePledge": "0",
"ReplacedSectorAge": 10101,
"ReplacedDayReward": "0",
"SectorKeyCID": null,
"SectorKeyCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"SimpleQAPower": true
}
]
@ -6032,7 +6111,9 @@ Inputs:
5432
],
"Expiration": 10101,
"UnsealedCid": null
"UnsealedCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
[
{
@ -6154,7 +6235,9 @@ Inputs:
5432
],
"Expiration": 10101,
"UnsealedCid": null
"UnsealedCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
[
{
@ -6337,7 +6420,9 @@ Response:
"ExpectedStoragePledge": "0",
"ReplacedSectorAge": 10101,
"ReplacedDayReward": "0",
"SectorKeyCID": null,
"SectorKeyCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"SimpleQAPower": true
}
]
@ -6470,7 +6555,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"GasCost": {
"Message": {
@ -6503,7 +6591,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -6547,7 +6638,10 @@ Response:
"MsgRct": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"Error": "string value",
"Duration": 60000000000,
@ -6618,7 +6712,10 @@ Response:
"Receipt": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"ReturnDec": {},
"TipSet": [
@ -6672,7 +6769,10 @@ Response:
"Receipt": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"ReturnDec": {},
"TipSet": [
@ -6761,7 +6861,9 @@ Response:
"ExpectedStoragePledge": "0",
"ReplacedSectorAge": 10101,
"ReplacedDayReward": "0",
"SectorKeyCID": null,
"SectorKeyCID": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
},
"SimpleQAPower": true
}
```
@ -6832,7 +6934,9 @@ Response:
5432
],
"Expiration": 10101,
"UnsealedCid": null
"UnsealedCid": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"PreCommitDeposit": "0",
"PreCommitEpoch": 10101
@ -6984,7 +7088,10 @@ Response:
"Receipt": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"ReturnDec": {},
"TipSet": [
@ -7041,7 +7148,10 @@ Response:
"Receipt": {
"ExitCode": 0,
"Return": "Ynl0ZSBhcnJheQ==",
"GasUsed": 9
"GasUsed": 9,
"EventsRoot": {
"/": "bafy2bzacea3wsdh6y3a36tb3skempjoxqpuyompjbmfeyf34fi3uy6uue42v4"
}
},
"ReturnDec": {},
"TipSet": [

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ COMMANDS:
log Manage logging
wait-api Wait for lotus api to come online
fetch-params Fetch proving parameters
evm Commands related to the Filecoin EVM runtime
NETWORK:
net Manage P2P Network
sync Inspect or interact with the chain syncer
@ -2568,6 +2569,95 @@ OPTIONS:
```
## lotus evm
```
NAME:
lotus evm - Commands related to the Filecoin EVM runtime
USAGE:
lotus evm command [command options] [arguments...]
COMMANDS:
deploy Deploy an EVM smart contract and return its address
invoke Invoke an EVM smart contract using the specified CALLDATA
stat Print eth/filecoin addrs and code cid
call Simulate an eth contract call
contract-address Generate contract address from smart contract code
help, h Shows a list of commands or help for one command
OPTIONS:
--help, -h show help (default: false)
```
### lotus evm deploy
```
NAME:
lotus evm deploy - Deploy an EVM smart contract and return its address
USAGE:
lotus evm deploy [command options] contract
OPTIONS:
--from value optionally specify the account to use for sending the creation message
--hex use when input contract is in hex (default: false)
```
### lotus evm invoke
```
NAME:
lotus evm invoke - Invoke an EVM smart contract using the specified CALLDATA
USAGE:
lotus evm invoke [command options] address calldata
OPTIONS:
--from value optionally specify the account to use for sending the exec message
--value value optionally specify the value to be sent with the invokation message (default: 0)
```
### lotus evm stat
```
NAME:
lotus evm stat - Print eth/filecoin addrs and code cid
USAGE:
lotus evm stat [command options] [arguments...]
OPTIONS:
--ethAddr value Ethereum address
--filAddr value Filecoin address
```
### lotus evm call
```
NAME:
lotus evm call - Simulate an eth contract call
USAGE:
lotus evm call [command options] [from] [to] [params]
OPTIONS:
--help, -h show help (default: false)
```
### lotus evm contract-address
```
NAME:
lotus evm contract-address - Generate contract address from smart contract code
USAGE:
lotus evm contract-address [command options] [senderEthAddr] [salt] [contractHexPath]
OPTIONS:
--help, -h show help (default: false)
```
## lotus net
```
NAME:

Some files were not shown because too many files have changed in this diff Show More