diff --git a/.circleci/config.yml b/.circleci/config.yml index dd8ad9417..2b28a1b46 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -686,6 +686,12 @@ workflows: - build suite: itest-eth_block_hash target: "./itests/eth_block_hash_test.go" + - test: + name: test-itest-eth_bytecode + requires: + - build + suite: itest-eth_bytecode + target: "./itests/eth_bytecode_test.go" - test: name: test-itest-eth_config requires: @@ -704,6 +710,12 @@ workflows: - build suite: itest-eth_deploy target: "./itests/eth_deploy_test.go" + - test: + name: test-itest-eth_fee_history + requires: + - build + suite: itest-eth_fee_history + target: "./itests/eth_fee_history_test.go" - test: name: test-itest-eth_filter requires: @@ -1040,13 +1052,6 @@ workflows: - build suite: conformance target: "./conformance" - - test-conformance: - name: test-conformance-bleeding-edge - requires: - - build - suite: conformance-bleeding-edge - target: "./conformance" - vectors-branch: specs-actors-v7 release: jobs: diff --git a/.circleci/template.yml b/.circleci/template.yml index 857f8f442..133984c39 100644 --- a/.circleci/template.yml +++ b/.circleci/template.yml @@ -571,13 +571,6 @@ workflows: - build suite: conformance target: "./conformance" - - test-conformance: - name: test-conformance-bleeding-edge - requires: - - build - suite: conformance-bleeding-edge - target: "./conformance" - vectors-branch: specs-actors-v7 release: jobs: diff --git a/Makefile b/Makefile index 43c362b86..023ca61f5 100644 --- a/Makefile +++ b/Makefile @@ -298,7 +298,7 @@ actors-gen: actors-code-gen fiximports .PHONY: actors-gen bundle-gen: - $(GOCC) run ./gen/bundle + $(GOCC) run ./gen/bundle $(RELEASE) $(GOCC) fmt ./build/... .PHONY: bundle-gen @@ -354,7 +354,7 @@ docsgen-openrpc-gateway: docsgen-openrpc-bin fiximports: ./scripts/fiximports -gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci bundle-gen fiximports +gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci fiximports @echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO MAKE docsgen-cli" .PHONY: gen diff --git a/api/api_full.go b/api/api_full.go index f3ab9e82b..15939d79d 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -786,15 +786,15 @@ type FullNode interface { 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 + 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, p jsonrpc.RawParams) (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 diff --git a/api/api_gateway.go b/api/api_gateway.go index 60f52aa7d..2e877fb1a 100644 --- a/api/api_gateway.go +++ b/api/api_gateway.go @@ -93,7 +93,7 @@ type Gateway interface { 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) + EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (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) diff --git a/api/mocks/mock_full.go b/api/mocks/mock_full.go index 799802c3c..41e7529ec 100644 --- a/api/mocks/mock_full.go +++ b/api/mocks/mock_full.go @@ -1014,18 +1014,18 @@ func (mr *MockFullNodeMockRecorder) EthEstimateGas(arg0, arg1 interface{}) *gomo } // EthFeeHistory mocks base method. -func (m *MockFullNode) EthFeeHistory(arg0 context.Context, arg1 ethtypes.EthUint64, arg2 string, arg3 []float64) (ethtypes.EthFeeHistory, error) { +func (m *MockFullNode) EthFeeHistory(arg0 context.Context, arg1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EthFeeHistory", arg0, arg1, arg2, arg3) + ret := m.ctrl.Call(m, "EthFeeHistory", arg0, arg1) 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 { +func (mr *MockFullNodeMockRecorder) EthFeeHistory(arg0, arg1 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) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EthFeeHistory", reflect.TypeOf((*MockFullNode)(nil).EthFeeHistory), arg0, arg1) } // EthGasPrice mocks base method. diff --git a/api/proxy_gen.go b/api/proxy_gen.go index 1198cc2ff..29a4e7131 100644 --- a/api/proxy_gen.go +++ b/api/proxy_gen.go @@ -252,7 +252,7 @@ type FullNodeMethods struct { 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"` + EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `perm:"read"` EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `perm:"read"` @@ -658,7 +658,7 @@ type GatewayMethods struct { 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) `` + EthFeeHistory func(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) `` EthGasPrice func(p0 context.Context) (ethtypes.EthBigInt, error) `` @@ -2051,14 +2051,14 @@ func (s *FullNodeStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) ( return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *FullNodeStruct) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { +func (s *FullNodeStruct) EthFeeHistory(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { if s.Internal.EthFeeHistory == nil { return *new(ethtypes.EthFeeHistory), ErrNotSupported } - return s.Internal.EthFeeHistory(p0, p1, p2, p3) + return s.Internal.EthFeeHistory(p0, p1) } -func (s *FullNodeStub) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { +func (s *FullNodeStub) EthFeeHistory(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { return *new(ethtypes.EthFeeHistory), ErrNotSupported } @@ -4218,14 +4218,14 @@ func (s *GatewayStub) EthEstimateGas(p0 context.Context, p1 ethtypes.EthCall) (e return *new(ethtypes.EthUint64), ErrNotSupported } -func (s *GatewayStruct) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { +func (s *GatewayStruct) EthFeeHistory(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { if s.Internal.EthFeeHistory == nil { return *new(ethtypes.EthFeeHistory), ErrNotSupported } - return s.Internal.EthFeeHistory(p0, p1, p2, p3) + return s.Internal.EthFeeHistory(p0, p1) } -func (s *GatewayStub) EthFeeHistory(p0 context.Context, p1 ethtypes.EthUint64, p2 string, p3 []float64) (ethtypes.EthFeeHistory, error) { +func (s *GatewayStub) EthFeeHistory(p0 context.Context, p1 jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { return *new(ethtypes.EthFeeHistory), ErrNotSupported } diff --git a/build/actors/pack.sh b/build/actors/pack.sh index c2060e67c..863a3c5c7 100755 --- a/build/actors/pack.sh +++ b/build/actors/pack.sh @@ -52,4 +52,4 @@ popd echo "Generating metadata..." -make -C ../../ bundle-gen +make -C ../../ RELEASE="$RELEASE" bundle-gen diff --git a/build/actors/v10.tar.zst b/build/actors/v10.tar.zst index d3a8e0a1e..8453eba42 100644 Binary files a/build/actors/v10.tar.zst and b/build/actors/v10.tar.zst differ diff --git a/build/actors/v9.tar.zst b/build/actors/v9.tar.zst index 55d0eba0b..f19c7db4c 100644 Binary files a/build/actors/v9.tar.zst and b/build/actors/v9.tar.zst differ diff --git a/build/bootstrap/butterflynet.pi b/build/bootstrap/butterflynet.pi index 556b5d14f..1def01c7c 100644 --- a/build/bootstrap/butterflynet.pi +++ b/build/bootstrap/butterflynet.pi @@ -1,2 +1,2 @@ -/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWKeDMuJbouvypr1nL2qRruhNVXzv4QiLsZRh6gnvLkc7p -/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWSsACNHLGoJbPqeitNY7tom19Nxq8x5ag36eTwmgcAeLo +/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWHkVVMJ1rfVLM5poNrgwTJiaDkpDLkPqQ9zVuNPQ7AJ6p +/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRyzqeQd51HCvVK3nvegmnBsYYPLSZbxR3Q9XAoUrUZ18 diff --git a/build/builtin_actors.go b/build/builtin_actors.go index 4d283919e..50aecde40 100644 --- a/build/builtin_actors.go +++ b/build/builtin_actors.go @@ -95,10 +95,11 @@ func loadManifests(netw string) error { } type BuiltinActorsMetadata struct { - Network string - Version actorstypes.Version - ManifestCid cid.Cid - Actors map[string]cid.Cid + Network string + Version actorstypes.Version + ManifestCid cid.Cid + Actors map[string]cid.Cid + BundleGitTag string } // ReadEmbeddedBuiltinActorsMetadata reads the metadata from the embedded built-in actor bundles. diff --git a/build/builtin_actors_gen.go b/build/builtin_actors_gen.go index 1f13ac6ed..70ab8e20b 100644 --- a/build/builtin_actors_gen.go +++ b/build/builtin_actors_gen.go @@ -7,8 +7,9 @@ import ( ) var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMetadata{{ - Network: "butterflynet", - Version: 8, + Network: "butterflynet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), @@ -29,52 +30,51 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), }, }, { - Network: "butterflynet", - Version: 9, - ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), + Network: "butterflynet", + Version: 9, + + ManifestCid: MustParseCid("bafy2bzacec35by4erhcdgcsgzp7yb3j57utydlxxfc73m3k5pep67ehvvyv6i"), Actors: map[string]cid.Cid{ - "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"), + "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"), }, }, { - Network: "butterflynet", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacedsgi3wpyd46hbktrleolnlepzsm6k466fcrxuc7keht4guokgxiy"), + Network: "butterflynet", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzacec4tgdtsrgbdywc5nzf5ekiw5zuefrasiahb4n5yqwcrwjzcdp4nk"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebz7dm3vcuqtzzcf5jwvcubz6ecqk52t5rsd36fyzka2iosy4l4ro"), - "cron": MustParseCid("bafk2bzacea6qtj2wkbe2wq5vxc2knlnj3vdvk4bkjp36xtazgzhnegd2uaj7m"), - "datacap": MustParseCid("bafk2bzacedwxkx3jz7qwv5iwozadz7t5hhw5dtlgdxuwqxdp6oqguas7nakjk"), - "eam": MustParseCid("bafk2bzacedoegh4idwvhjqahfnbqq6aqzgccgjwumudx6ihfut36ng57or7fi"), - "ethaccount": MustParseCid("bafk2bzacebn6l3x7d2i6lv72osbgcl4a37imexh5ou5kvbmj56taetwcyyhgq"), - "evm": MustParseCid("bafk2bzaced5gaxg5mz3hho473aszx5brgjriicqgrcbqctnyyn2e6vcxv3ule"), - "init": MustParseCid("bafk2bzacecbo6ggprh7sz3oy6uu5raykwngqmnjdsiijdrgp4glet3mb65ywo"), - "multisig": MustParseCid("bafk2bzacecmu3bhbg4rh5sqbagjlvrpb6ip5k3pngq22a33ok44yuhk75zenq"), - "paymentchannel": MustParseCid("bafk2bzacebth7fqe5xts6hbm7m6n733qcu6b6atd7ur6l7jhddferjgpxdy4s"), + "account": MustParseCid("bafk2bzaceae6holtld4caox2xood5rpcjotrxj7lnfxvfmhivb3s2ddyj22qw"), + "cron": MustParseCid("bafk2bzaceab2vrkun6ps3hactaumfzgm6zk4sdasiqiedxzdttkvw64hndcdg"), + "datacap": MustParseCid("bafk2bzacecixx45mf6chwktsd2g5krlr35p3g7pkkrvzjeujz4ryhlztpl7fq"), + "eam": MustParseCid("bafk2bzaceciekaxrlgnmosmthbgptpdu2bzdoo7mt67p7cqbdvnxup6xpd6ns"), + "ethaccount": MustParseCid("bafk2bzacecb4ttgbjzkaqrg7phqgao2kxsgeet4wnrr5qmftlfad26v6jpk4o"), + "evm": MustParseCid("bafk2bzacecrwejr7bedjww67ppof3abb6df66w76r7wpuzc426arc4oibndeu"), + "init": MustParseCid("bafk2bzacea5ke6q7je2ofrai7dpw67vat463d5f74g4evvwtcu7dhp4ff6ztk"), + "multisig": MustParseCid("bafk2bzacecs6aws25bvqmyzny3vcilr2xw35jymryu4yzodg7l7gf4bhjpolw"), + "paymentchannel": MustParseCid("bafk2bzacedtewkfsicz2rm4hsjsbagrl2mhmqfdikpsq3ggoct5iqa6caka6a"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceds7hy7v77k2jsbkfob7b2qor6v5s2oancfxhkuuzwqqg6kxk27xe"), - "storagemarket": MustParseCid("bafk2bzacebqi6ylwfmack3hfzw6eej7r6gwlbxzo33tdkfkpof7wg7h54pjtw"), - "storageminer": MustParseCid("bafk2bzacedsxpkqqiycn5tjydycnlqer4544mpqvtwfamwyq6hwz7yjqd3iry"), - "storagepower": MustParseCid("bafk2bzacedssirrse7ufxti6capgf2qufb6y3oatv2fnnnh7xrgp47x3hfox4"), - "system": MustParseCid("bafk2bzacea2lod7lxod72voxyik5btpzmpvduddr4hwshcsyyy257izh6kut4"), - "verifiedregistry": MustParseCid("bafk2bzacebss7ol4ay6nkg7r3c2355aqpku4yvqipyh3sgdrxkhsrssrsaaig"), + "reward": MustParseCid("bafk2bzacecqmh47zzzlzbtaueaz2fvhiqnktccfrcqicul4j6tca2bruvtn44"), + "storagemarket": MustParseCid("bafk2bzacecbvqe4k6jyvwovxfnkylj3zpb2vjxkc3ar53x7c2pe5mkokxuyk6"), + "storageminer": MustParseCid("bafk2bzaceczbh2aofwcif4aqycydmnsjkkww4i4yfl4zca5j2dqopbz46dvrg"), + "storagepower": MustParseCid("bafk2bzacealioyiirrvov5rnh63omtsifppcsgba7my2tp7bslhd454wczepy"), + "system": MustParseCid("bafk2bzaceax2qvj3ap2dxvzgjps2vtmfgfrej3hdgk7a5euqdgsmak7ptalaa"), + "verifiedregistry": MustParseCid("bafk2bzaceaeqg3nqpjrgklq6nli6hz73s76hp4bwn6jsa64y22dj3csvmcl32"), }, }, { - Network: "calibrationnet", - Version: 8, + Network: "calibrationnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedrdn6z3z7xz7lx4wll3tlgktirhllzqxb766dxpaqp3ukxsjfsba"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecruossn66xqbeutqx5r4k2kjzgd43frmwd4qkw6haez44ubvvpxo"), @@ -90,8 +90,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceaihibfu625lbtzdp3tcftscshrmbgghgrc7kzqhxn4455pycpdkm"), }, }, { - Network: "calibrationnet", - Version: 9, + Network: "calibrationnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacedbedgynklc4dgpyxippkxmba2mgtw7ecntoneclsvvl4klqwuyyy"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceavfgpiw6whqigmskk74z4blm22nwjfnzxb4unlqz2e4wg3c5ujpw"), @@ -108,30 +109,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebh7dj6j7yi5vadh7lgqjtq42qi2uq4n6zy2g5vjeathacwn2tscu"), }, }, { - Network: "calibrationnet", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacec4ilfymf3sorrfxp67ruwbax3a4mbqzic63vy2xlfh3ulky3bxvs"), + Network: "calibrationnet", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzaced25ta3j6ygs34roprilbtb3f6mxifyfnm7z7ndquaruxzdq3y7lo"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacecupizfd6xbts7blvn3ozouy3f2gtehwl7qohjks54nsomtzs3aki"), - "cron": MustParseCid("bafk2bzacedry7eqweymdnybq5jm5slizm67v4ffhv7zqiw2jwevr7ijv25gjc"), - "datacap": MustParseCid("bafk2bzacebq6vigteuwchk7si6y45ogrfu2zpxjbo4a54btnbhp3rc3ifghx6"), - "eam": MustParseCid("bafk2bzacebounosssmuaz35xpyuupvijbcwqyaumbeztqmigbihfw2ysbnx4w"), - "ethaccount": MustParseCid("bafk2bzacebi2ymbi5wo2o3rp2x6cqo55vroixngmpbdcs7el4rq4hvacyzsqy"), - "evm": MustParseCid("bafk2bzaceapklwjzdzkmnfprn5wsjdzjnueuw2ke4kixq46gnbwjncns4dleu"), - "init": MustParseCid("bafk2bzaced7u4zpkxh5ecjo2emwsrk3vnickhmkxy22garqf766nbxcewymy6"), - "multisig": MustParseCid("bafk2bzacedlunqzd3mxslb7zej5fsti2jxredfhtcqqxepng67t4zfiv6lwlc"), - "paymentchannel": MustParseCid("bafk2bzacea4z2yi33rfiiutkmqko33fslikmeqgypkiam5cqpeylyp3oup552"), + "account": MustParseCid("bafk2bzacebhfuz3sv7duvk653544xsxhdn4lsmy7ol7k6gdgancyctvmd7lnq"), + "cron": MustParseCid("bafk2bzacecw2yjb6ysieffa7lk7xd32b3n4ssowvafolt7eq52lp6lk4lkhji"), + "datacap": MustParseCid("bafk2bzaceaot6tv6p4cat3cg5fknq22htosw3p5rwyijmdsraatwqyc4qyero"), + "eam": MustParseCid("bafk2bzacec5untyj6cefdsfm47wckozw6wt6svqqh5dzh63nu4f6dvf26fkco"), + "ethaccount": MustParseCid("bafk2bzacebiyrhz32xwxi6xql67aaq5nrzeelzas472kuwjqmdmgwotpkj35e"), + "evm": MustParseCid("bafk2bzaceblpgzid4qjfavuiht6uwvq2lznshklk2qmf5akm3dzx2fczdqdxc"), + "init": MustParseCid("bafk2bzacedhxbcglnonzruxf2jpczara73eh735wf2kznatx2u4gsuhgqwffq"), + "multisig": MustParseCid("bafk2bzacebv5gdlte2pyovmz6s37me6x2rixaa6a33w6lgqdohmycl23snvwm"), + "paymentchannel": MustParseCid("bafk2bzacea7ngq44gedftjlar3j3ql3dmd7e7xkkb6squgxinfncybfmppmlc"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzacea4dnvun5vwzunhgepejrknukx2di2kmo3x4akz6rollq5icsrl3m"), - "storagemarket": MustParseCid("bafk2bzaceafoon3fsl756rbrih4upar3ayi6746gaj756bk56thncpotl4coa"), - "storageminer": MustParseCid("bafk2bzacea3dj37h74ue2jtief3bj2shxagigygcm2h6purgp42mr6swwfdiw"), - "storagepower": MustParseCid("bafk2bzacebmodckd4tustgfmeilcfi3ovd4wzxz2hnd6vyhkq7hgiojiy3cc6"), - "system": MustParseCid("bafk2bzacebpqirxha42noejsk5miv5kip44eay6lm63pxt26xhlwdmn7tnqaq"), - "verifiedregistry": MustParseCid("bafk2bzaceczf7qrddwt5kh3gvro25wpls346tanffeatk7nsczjnwb7jtd454"), + "reward": MustParseCid("bafk2bzacea3yo22x4dsh4axioshrdp42eoeugef3tqtmtwz5untyvth7uc73o"), + "storagemarket": MustParseCid("bafk2bzacecclsfboql3iraf3e66pzuh3h7qp3vgmfurqz26qh5g5nrexjgknc"), + "storageminer": MustParseCid("bafk2bzacedu4chbl36rilas45py4vhqtuj6o7aa5stlvnwef3kshgwcsmha6y"), + "storagepower": MustParseCid("bafk2bzacedu3c67spbf2dmwo77ymkjel6i2o5gpzyksgu2iuwu2xvcnxgfdjg"), + "system": MustParseCid("bafk2bzacea4mtukm5zazygkdbgdf26cpnwwif5n2no7s6tknpxlwy6fpq3mug"), + "verifiedregistry": MustParseCid("bafk2bzacec67wuchq64k7kgrujguukjvdlsl24pgighqdx5vgjhyk6bycrwnc"), }, }, { - Network: "caterpillarnet", - Version: 8, + Network: "caterpillarnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -152,8 +155,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "caterpillarnet", - Version: 9, + Network: "caterpillarnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -174,30 +178,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "caterpillarnet", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacec36gpvghhgjwa5ya3ocxg33pct2vddegeixgkpqsc6eiyajdjkii"), + Network: "caterpillarnet", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzacedn6med544h6r7frzvyq5cvd7dqgnwgpmzgf42d4agoysx6tf475i"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebcl3xlk7i6t5tau2rfgxft5pu6qzvjqxo6zs5guerz3xarxztyv6"), - "cron": MustParseCid("bafk2bzacebhoqjvaxtzj3k4tz7c4vtt4or4u3h3jhwxlh3t4l6by2ota3s7by"), - "datacap": MustParseCid("bafk2bzaceb7ttn3d43yb7l5ok5rjgr7325jb6ds4air7mivgoyzp5p4gwgrq4"), - "eam": MustParseCid("bafk2bzacebobuasaev75fge6xg6bekrdvnyox4h7iluupt4wqq2n4expha2oe"), - "ethaccount": MustParseCid("bafk2bzaceaghtv45mm6qx3yrxwy7zz7x7mqj4n4lzw4hx7zxzlij6dcxxuv4c"), - "evm": MustParseCid("bafk2bzacecu7xpnpw27jquvnpfv4rseaal477ml4ouxy37eo7wymgfzkexllg"), - "init": MustParseCid("bafk2bzacea2rnkho4nliqvisiqgtqx66c4xneagpgj52tyqa64grxadggylbk"), - "multisig": MustParseCid("bafk2bzacebak6spthfa23cyqjmpgkgku4gg4egdn2zc6vkikbh5ongadzakma"), - "paymentchannel": MustParseCid("bafk2bzaceb3tib72pwze2rov72ldwlfv3otes3tejgnfpbrzahwb5xi7slhqm"), + "account": MustParseCid("bafk2bzaceaysjus6ldo45qnedaopwctamtvvk4ga2l4dh7dmdtltsfin4puuk"), + "cron": MustParseCid("bafk2bzaceatq2ltzs2p37nniek3qpkitzlfd7iu2qtupzjtgvtggxglrhj7ay"), + "datacap": MustParseCid("bafk2bzacecgwe56okusbtsfimiwstxe7ova25uvrkj4osk3w5wl2qclvd64bi"), + "eam": MustParseCid("bafk2bzaceak3xbmmyj5glnm65kv5p7zc6u7x2xallwpz7aphqqouadn3jvumm"), + "ethaccount": MustParseCid("bafk2bzacec5bcn2i4ktsc54wx7gf4gwdd6xjcukh43szfya47jicxlwrhfrhk"), + "evm": MustParseCid("bafk2bzacebbc2iv4tw2kfmmcm7k3uxilpqvbjg6jsqbov4n7wqcxvvmtazfbc"), + "init": MustParseCid("bafk2bzacecvlqa2szdyem4gwgks2yk7bfernmzbxgo5felnpqgikyesdyiury"), + "multisig": MustParseCid("bafk2bzacebvqjxop2ald5f5hvu7qqb7ali7iluxcbdd3ssllawco6kafjteqw"), + "paymentchannel": MustParseCid("bafk2bzacebux5gmkddtur2kfebwzrxwqyqh2almlt4bw3v7f4bg3gy2zqjhbe"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceak3n3orgdraub4bqiy3paio77hu4laaqv4vf7wmwv4ybl5ahgi5o"), - "storagemarket": MustParseCid("bafk2bzacearo7sog7yqbrwyws5o3lbsdsjf2cp5vsoxc4u3s5atgjtwzzh65s"), - "storageminer": MustParseCid("bafk2bzacecrzmjrbqjwknnkybdexspb6gfu4q6dvtaeguxl26yuytsjc3w7ws"), - "storagepower": MustParseCid("bafk2bzaceavlmlu4mt2u7xwnnzf6vwdmh2yo76aauujwlgsbfhafjgxb4zgtg"), - "system": MustParseCid("bafk2bzacec35rgzpiaa4n3r5bzgssk33bhfgozjvgunbwax32dooqqokfe6ag"), - "verifiedregistry": MustParseCid("bafk2bzacebjfkrzihgzlb2jecgm5seoqwf5e656zc22vjoyclioru6vdy2bnm"), + "reward": MustParseCid("bafk2bzacebhm5w7q7wlxrwgbldolzq5qfcdmcu66j6ty37ppvpwafxzlizxn4"), + "storagemarket": MustParseCid("bafk2bzacebgniq7x22ep4oiithvlzepxo5jsvhuang2vqfz3prozihmviw5ey"), + "storageminer": MustParseCid("bafk2bzacecchnrfi4cgbpis4aagiqkhalgqudjlu25da7rer4ltlgpojersgm"), + "storagepower": MustParseCid("bafk2bzaceaxomr5xbhacbbn5ib6unekjz6igoqr4r4a2taxqcpyb4gpwi6zvk"), + "system": MustParseCid("bafk2bzacebmymcxtwkk6dzgtmkbradncjpsxdqkcwtemhio5acvpm742rguv6"), + "verifiedregistry": MustParseCid("bafk2bzaceae5zbc2h6gpyu6uzsvelvww53p5mujq2dvs3zi74w6mvnigwc3va"), }, }, { - Network: "devnet", - Version: 8, + Network: "devnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedq7tuibavyqxzkq4uybjj7ly22eu42mjkoehwn5d47xfunmtjm4k"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacea4tlgnp7m6tlldpz3termlwxlnyq24nwd4zdzv4r6nsjuaktuuzc"), @@ -213,8 +219,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceaajgtglewgitshgdi2nzrvq7eihjtyqj5yiamesqun2hujl3xev2"), }, }, { - Network: "devnet", - Version: 9, + Network: "devnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaced5llqnqqhypolyuogz3h2wjomugqkrhyhocvly3aoib4c5xiush6"), @@ -231,30 +238,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacednorhcy446agy7ecpmfms2u4aoa3mj2eqomffuoerbik5yavrxyi"), }, }, { - Network: "devnet", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacebemt6rdgtsj5vhv2iimbdvm5g4xllgl7nugxvuuthsedncmfakww"), + Network: "devnet", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzaceco52tjbexpijsegolhdkhlziflum4bl27hcjrpnny273t3lsa6tc"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzaceajmds6zbz235lbjjhv3mxc6x3kqudjkxedh5xqvlemh3f6xslz76"), - "cron": MustParseCid("bafk2bzaceabbv5ej2yd3n7txl3s4pahknb4in5dok57hzwfheqnk6k67zegbk"), - "datacap": MustParseCid("bafk2bzaceayzgq7qpuc5pr4lrh6k3xnvmirlmutffplmgur4pvcaynpxlkph6"), - "eam": MustParseCid("bafk2bzacecrand7mp7q3jm3u5dpqm4o24ki3pk3uzcw4zonjcowq4rxwptsis"), - "ethaccount": MustParseCid("bafk2bzacecpwfxpvqiyiisbfw45v5ottcstxu2vifji3xswxt3jzk4vcrs4g4"), - "evm": MustParseCid("bafk2bzaceajrtntc5urxkwbzdu3khi2eqvarnfx6vh7luqt33gn6z4a4kjkj6"), - "init": MustParseCid("bafk2bzaced6npj5zrjb3lxhgtsq4st66dvde56nftbvchmpid3rcazfvnqkpk"), - "multisig": MustParseCid("bafk2bzacealhbd4slci4o76dpdurkkk3q5busopediwfh7uis4hfh7tzghzni"), - "paymentchannel": MustParseCid("bafk2bzacebvpkvrihus53sdyutsjsbpfefe5gd2amfb6zkztdfp6g2m4ubqrk"), + "account": MustParseCid("bafk2bzacec6mdvynyu4cxb53tcdbkcu7w7jzxduxqqadi2y2rx2tsm42627tk"), + "cron": MustParseCid("bafk2bzaceaiscwdpdzdooja7hwz56ee3zztjogl4gljkccpefi7uliqtaq2ek"), + "datacap": MustParseCid("bafk2bzacedmfwrwwqmwxtfpvhp33mvt5btq2ewbjfrvfetwnrxt5r37i3ymzk"), + "eam": MustParseCid("bafk2bzaced2lwwrqtkgwxdgadpdbxpxjoh2gsunjg3bgtoubs47p7fbktbu26"), + "ethaccount": MustParseCid("bafk2bzacea5zob56gdcxudkubhol4gijzgwgtaaix4pmv3vpg4ihtsuxbdhqa"), + "evm": MustParseCid("bafk2bzaceacw53ajmggrugzfiag75suv27hvqoduypk24xru3cumctpxotbya"), + "init": MustParseCid("bafk2bzaceahgtz6647nbarvyjwtvjadzd2i2m75jv6nnrq3kgwrjxnvkykmhs"), + "multisig": MustParseCid("bafk2bzaceduhknhgd45j5aey7c7pszbbwqm4vuih4iwbuffjxekqteebuja5q"), + "paymentchannel": MustParseCid("bafk2bzacec5x44xqfgmdvsxr4nwzbcwaotodzffsjsslw64xblr7xgx7jr6c4"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceaftaidppnno2dzhpxl5vyti5mcmdhvheieanwvptgacuj5ozzloe"), - "storagemarket": MustParseCid("bafk2bzacea75td2k2cdwc2o4kotdods2thomhcoqg5rf62ty6gkuxojknziae"), - "storageminer": MustParseCid("bafk2bzaceapj5q7egywl3zovwcm4hpbvr4vjtoshj57ncqg3srzseweyclvug"), - "storagepower": MustParseCid("bafk2bzacebbraebsoin6hhmr4na56st4gyg7yd7p2ry2igegnvws7deq32hec"), - "system": MustParseCid("bafk2bzacedtw3mq5zyxxbnybnjegqyrz3ufiboeoipyzynlk6zgyumvl3267g"), - "verifiedregistry": MustParseCid("bafk2bzacecaqciqoky2z7win5rkzd3gkgpa3345adjyiidmg4swmw5celeb3a"), + "reward": MustParseCid("bafk2bzacebzyuwya26rjjxmtzcszf5hcv54b3l7bz6hbflbx3wmpycbqcq6fa"), + "storagemarket": MustParseCid("bafk2bzaceav2nt4ek457u3ngn7da2gaqblwdumpzhsohp4d7whmubvarkllac"), + "storageminer": MustParseCid("bafk2bzacecxr3rdjaive7opvfyqv3p7tft6ragdozlqd6hciprlknda7u5hk6"), + "storagepower": MustParseCid("bafk2bzaceabvb7af55pgm3xpcc7lqjaupw3dyyokbmhjvbo2ebelizalmugfq"), + "system": MustParseCid("bafk2bzacecp7sswldmz6cbl7lh6y5vtwnn43mvdkgcazcyjjcpjjbtydb2f3w"), + "verifiedregistry": MustParseCid("bafk2bzaced27273xjvuyhxlne2kmbrbtupcxxpdchqbkiyr3dcqoijaok2k7e"), }, }, { - Network: "hyperspace", - Version: 8, + Network: "hyperspace", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), @@ -275,30 +284,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "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: "mainnet", - Version: 8, + Network: "mainnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacebogjbpiemi7npzxchgcjjki3tfxon4ims55obfyfleqntteljsea"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedudbf7fc5va57t3tmo63snmt3en4iaidv4vo3qlyacbxaa6hlx6y"), @@ -314,8 +302,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceb3zbkjz3auizmoln2unmxep7dyfcmsre64vnqfhdyh7rkqfoxlw4"), }, }, { - Network: "mainnet", - Version: 9, + Network: "mainnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacect2p7urje3pylrrrjy3tngn6yaih4gtzauuatf2jllk3ksgfiw2y"), @@ -332,30 +321,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacecf3yodlyudzukumehbuabgqljyhjt5ifiv4vetcfohnvsxzynwga"), }, }, { - Network: "mainnet", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacec2ggeabyyl2cjaqmcpnyvjirrrm6bfc7d73q4pekm27hybzdqs3q"), + Network: "mainnet", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzacecyg4biu2uccoekdzen4qxf4qt24deyx6j5rpwfys7qp6lixvzsxo"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebdlwwnd57vd2444wrfe5amtf2f6htqj3hdh4fxblywdbynrurhgy"), - "cron": MustParseCid("bafk2bzacecxmaxh272zhgmayfg7btvq5lshv2cd7njkarlbbikba4otiaboyg"), - "datacap": MustParseCid("bafk2bzaceb64wicovvrjzaotvs64hmdtvolw4l6qanwp5tk56okzqbfttxck2"), - "eam": MustParseCid("bafk2bzacedxs56zywfumzcv7i5fwluku2qevg54cuiuwi5d3pavf3rilfu33g"), - "ethaccount": MustParseCid("bafk2bzacecepsmgsucfebvbwf5vebm7j6zeqaz3ub52warxqobqeymh5vdjik"), - "evm": MustParseCid("bafk2bzacecf6arqbso67nmrhcsjvyradrbbv7hs2noand27fyr4nfilms4znu"), - "init": MustParseCid("bafk2bzaceat2xcem5lko5ot4mmrowtm6ehx5klw7c4ss4vxma55tyfvvxwlge"), - "multisig": MustParseCid("bafk2bzacebz43omxi5vtkidhsxroqtgkpxtftdj6poew3744fayfftgdebe4y"), - "paymentchannel": MustParseCid("bafk2bzaceds4ob3ev2ie2vorhfomddd44otqfau4d4eogfofjjbjjx2h27nh2"), + "account": MustParseCid("bafk2bzacect72amqxedrtjymuq5lfrskk2itnniyfa5gdvqp5sjoeeb33oi2e"), + "cron": MustParseCid("bafk2bzaceb3nfsu5jbftadzxy24caz4tlgi6476yml25tfq2g7higtgnifys4"), + "datacap": MustParseCid("bafk2bzacec3s7oovwjxdx3hnhtqr75fsvhj7p4545gedt3kf2iuaw7zqhym2c"), + "eam": MustParseCid("bafk2bzacebw4ye6kvufarvrtqebs57idw6ydtzli7egd4h2t33jwoi547trra"), + "ethaccount": MustParseCid("bafk2bzaceavrimh4mcla6zi25uhs3ystix2n5rp4kfqeiewkh337zpjbo3egq"), + "evm": MustParseCid("bafk2bzacecnsk2ydh2q6wxf2fzsvivo6cfrka3jos62io2ds2xou4gl2byqvw"), + "init": MustParseCid("bafk2bzacebb3l4gw6hfszizw5zwho3pfpnmgrmxqm4ie42dgn62325lo4vwc2"), + "multisig": MustParseCid("bafk2bzacedi6ii3ewygygjukn4viros3uiztonnf6tg6b3ppqk4pdtqrwgeuw"), + "paymentchannel": MustParseCid("bafk2bzacebwqqfhodha2jl7tbws3dpy2dkngepbllqx6hy72zdokui3ow6eeq"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaced7xvqx7n6426lls4ao54exn63pv73m7makxf7ygb575roqxhjuuw"), - "storagemarket": MustParseCid("bafk2bzaceb5piewkvdj4ee6b4qzhimixjzee5z3hsuwdjksncpvef7sgaw6rw"), - "storageminer": MustParseCid("bafk2bzaceacukfushmnsqtdvtdyx2in6o2el7jq46qo7iaxgwytel4oz5srv4"), - "storagepower": MustParseCid("bafk2bzacedi6z45jcms5guns4qxi6rs2e2prc6mpnhkr4klljrra3ayfburss"), - "system": MustParseCid("bafk2bzacedy7ssu2hez3nu7bi4j6ucojty4sfaublxlxhfd3tkgzyrm5sdxbq"), - "verifiedregistry": MustParseCid("bafk2bzacecjgudirfyzyroq3xhf2bldl636w7prexcvo7v3xqdijzcom4rgry"), + "reward": MustParseCid("bafk2bzacedbeexrv2d4kiridcvqgdatcwo2an4xsmg3ckdrptxu6c3y7mm6ji"), + "storagemarket": MustParseCid("bafk2bzacedalaigmokrtimabt7y7bkok5nd2j5gmifdahht3dsz5ulj7vxdgu"), + "storageminer": MustParseCid("bafk2bzacecpq5wjp3frz3b4cd2pozegi7sykgcawnaowjm6ddyai2epbphxvw"), + "storagepower": MustParseCid("bafk2bzacedfxlpyj5uxlh5uuhl55lazmhm7q6pr3qoywxb25qrytbptpy7zb6"), + "system": MustParseCid("bafk2bzacecbscw26oyfgdse6y6ij5fqtaq5uo2ehfom26mle4rk4ann2xf2jq"), + "verifiedregistry": MustParseCid("bafk2bzaceanpda37bvefmzfemikyokwnspzxdxqz5kriaqex4hpevdhphu6sq"), }, }, { - Network: "testing", - Version: 8, + Network: "testing", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedkjpqx27wgsvfxzuxfvixuxtbpt2y6yo6igcasez6gqiowron776"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), @@ -371,8 +362,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacectzxvtoselhnzsair5nv6k5vokvegnht6z2lfee4p3xexo4kg4m6"), }, }, { - Network: "testing", - Version: 9, + Network: "testing", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacecnnrmekqw2xvud46g3vo6x26cogh3ydgljqajlxqxzzbuxsjlwjm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), @@ -389,30 +381,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceatmqip2o3ausbntvdhj7yemu6hb3b5yqv6hm42gylbbmz7geocpm"), }, }, { - Network: "testing", - Version: 10, - ManifestCid: MustParseCid("bafy2bzacedhivj4zbumou6d3242p3ecqhlqfcjfskdv46uzjchlj3ve23xyoa"), + Network: "testing", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzacedjgfy7dmbd4i3io5r47eokprndhucdvwaxqyw4ijhhtldhewojk4"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), - "cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), - "datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), - "eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), - "ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), - "evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), - "init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), - "multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), - "paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), + "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"), + "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"), + "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"), + "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"), + "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"), + "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"), + "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"), + "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"), + "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), - "storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), - "storageminer": MustParseCid("bafk2bzacecx2fs3ra4ydxvwq6oh73esqy2xjqhwsnfrdl5ctbg26zem77zy3u"), - "storagepower": MustParseCid("bafk2bzacedwfnzestwv7ylleeuk3fhp6jewc4ygw3fgodsciww7gw5ilt4ony"), - "system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), - "verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), + "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"), + "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"), + "storageminer": MustParseCid("bafk2bzacednqbtebg7xxsr2sle42pfxmz5chxn32bsjssgc3mzt7iw2eevaly"), + "storagepower": MustParseCid("bafk2bzacebovido4zxtywaz32ejagvtk4v7z5w5nwxrflaldsf56xd7pecu4w"), + "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"), + "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"), }, }, { - Network: "testing-fake-proofs", - Version: 8, + Network: "testing-fake-proofs", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacecd3lb5v6tzjylnhnrhexslssyaozy6hogzgpkhztoe76exbrgrug"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), @@ -428,8 +422,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacectzxvtoselhnzsair5nv6k5vokvegnht6z2lfee4p3xexo4kg4m6"), }, }, { - Network: "testing-fake-proofs", - Version: 9, + Network: "testing-fake-proofs", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacecql2gj2tri4fnbznmldue73qzt6zszvugw4exd64mwb52zrhv7k2"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), @@ -446,25 +441,26 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceatmqip2o3ausbntvdhj7yemu6hb3b5yqv6hm42gylbbmz7geocpm"), }, }, { - Network: "testing-fake-proofs", - Version: 10, - ManifestCid: MustParseCid("bafy2bzaceav36pezxhapk6vlgohdp6jiydk44o6xowltjnyhu3nrhpfcby5zs"), + Network: "testing-fake-proofs", + Version: 10, + + ManifestCid: MustParseCid("bafy2bzaceblvi7d3yosakpuux27gqzr34gcjr6a2f6uzbyagmwybgfsk4xeu2"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), - "cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), - "datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), - "eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), - "ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), - "evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), - "init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), - "multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), - "paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), + "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"), + "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"), + "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"), + "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"), + "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"), + "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"), + "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"), + "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"), + "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), - "storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), - "storageminer": MustParseCid("bafk2bzacebp3rj6d4g2ppngw2xp7okzqx6oapfk6xi54n3aqenadqvptlk45g"), - "storagepower": MustParseCid("bafk2bzacedhwtksxb6orm63doxx2bgcy6fpy5li5prjb3twsxdh75anjbmdug"), - "system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), - "verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), + "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"), + "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"), + "storageminer": MustParseCid("bafk2bzaceaoaduzssj46mse6gizcy764ingsgvuavafkowf4vexluindct3ji"), + "storagepower": MustParseCid("bafk2bzacedqvicpfdcegfsj6p4rb3judx7v5v6trpnca7djbim4pts5appis4"), + "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"), + "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"), }, }} diff --git a/build/builtin_actors_test.go b/build/builtin_actors_test.go index 858a8b3a1..bb133bdab 100644 --- a/build/builtin_actors_test.go +++ b/build/builtin_actors_test.go @@ -17,7 +17,13 @@ func TestEmbeddedMetadata(t *testing.T) { metadata, err := build.ReadEmbeddedBuiltinActorsMetadata() require.NoError(t, err) - require.Equal(t, metadata, build.EmbeddedBuiltinActorsMetadata) + for i, v1 := range metadata { + v2 := build.EmbeddedBuiltinActorsMetadata[i] + require.Equal(t, v1.Network, v2.Network) + require.Equal(t, v1.Version, v2.Version) + require.Equal(t, v1.ManifestCid, v2.ManifestCid) + require.Equal(t, v1.Actors, v2.Actors) + } } // Test that we're registering the manifest correctly. diff --git a/build/genesis/butterflynet.car b/build/genesis/butterflynet.car index 71a1c684e..cb0c4162b 100644 Binary files a/build/genesis/butterflynet.car and b/build/genesis/butterflynet.car differ diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index eba170151..952af5430 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 395877f11..3f6c25090 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/build/params_butterfly.go b/build/params_butterfly.go index 7cd02bce9..b00381b44 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -19,7 +19,7 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } -const GenesisNetworkVersion = network.Version16 +const GenesisNetworkVersion = network.Version17 var NetworkBundle = "butterflynet" var BundleOverrides map[actorstypes.Version]string diff --git a/chain/actors/builtin/evm/actor.go.template b/chain/actors/builtin/evm/actor.go.template index d20db6bcb..aa23b5f11 100644 --- a/chain/actors/builtin/evm/actor.go.template +++ b/chain/actors/builtin/evm/actor.go.template @@ -49,4 +49,8 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecode() ([]byte, error) + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go index 120ca66f8..f55a2177d 100644 --- a/chain/actors/builtin/evm/evm.go +++ b/chain/actors/builtin/evm/evm.go @@ -49,4 +49,8 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecode() ([]byte, error) + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/state.go.template b/chain/actors/builtin/evm/state.go.template index acc78dc0f..eb55a8463 100644 --- a/chain/actors/builtin/evm/state.go.template +++ b/chain/actors/builtin/evm/state.go.template @@ -21,12 +21,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { func make{{.v}}(store adt.Store, bytecode cid.Cid) (State, error) { out := state{{.v}}{store: store} - s, err := evm{{.v}}.ConstructState(store, bytecode) - if err != nil { - return nil, err - } + s, err := evm{{.v}}.ConstructState(store, bytecode) + if err != nil { + return nil, err + } - out.State = *s + out.State = *s return &out, nil } @@ -42,4 +42,26 @@ func (s *state{{.v}}) Nonce() (uint64, error) { func (s *state{{.v}}) GetState() interface{} { return &s.State -} \ No newline at end of file +} + +func (s *state{{.v}}) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state{{.v}}) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state{{.v}}) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/chain/actors/builtin/evm/v10.go b/chain/actors/builtin/evm/v10.go index 78a4a2383..77a09037b 100644 --- a/chain/actors/builtin/evm/v10.go +++ b/chain/actors/builtin/evm/v10.go @@ -3,6 +3,7 @@ package evm import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -43,3 +44,25 @@ func (s *state10) Nonce() (uint64, error) { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state10) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state10) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/chain/consensus/compute_state.go b/chain/consensus/compute_state.go index dd0386341..747992e0a 100644 --- a/chain/consensus/compute_state.go +++ b/chain/consensus/compute_state.go @@ -92,11 +92,11 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, }() ctx = blockstore.WithHotView(ctx) - makeVmWithBaseStateAndEpoch := func(base cid.Cid, e abi.ChainEpoch) (vm.Interface, error) { + makeVm := func(base cid.Cid, e abi.ChainEpoch, timestamp uint64) (vm.Interface, error) { vmopt := &vm.VMOpts{ StateBase: base, Epoch: e, - Timestamp: ts.MinTimestamp(), + Timestamp: timestamp, Rand: r, Bstore: sm.ChainStore().StateBlockstore(), Actors: NewActorRegistry(), @@ -142,10 +142,22 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, return nil } + // May get filled with the genesis block header if there are null rounds + // for which to backfill cron execution. + var genesis *types.BlockHeader + + // There were null rounds in between the current epoch and the parent epoch. for i := parentEpoch; i < epoch; i++ { var err error if i > parentEpoch { - vmCron, err := makeVmWithBaseStateAndEpoch(pstate, i) + if genesis == nil { + if genesis, err = sm.ChainStore().GetGenesis(ctx); err != nil { + return cid.Undef, cid.Undef, xerrors.Errorf("failed to get genesis when backfilling null rounds: %w", err) + } + } + + ts := genesis.Timestamp + build.BlockDelaySecs*(uint64(i)) + vmCron, err := makeVm(pstate, i, ts) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("making cron vm: %w", err) } @@ -172,7 +184,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, partDone() partDone = metrics.Timer(ctx, metrics.VMApplyMessages) - vmi, err := makeVmWithBaseStateAndEpoch(pstate, epoch) + vmi, err := makeVm(pstate, epoch, ts.MinTimestamp()) if err != nil { return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err) } diff --git a/chain/events/filter/event.go b/chain/events/filter/event.go index dfb61f111..b821a2f83 100644 --- a/chain/events/filter/event.go +++ b/chain/events/filter/event.go @@ -105,18 +105,9 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever continue } - entries := make([]types.EventEntry, len(ev.Entries)) - for i, entry := range ev.Entries { - entries[i] = types.EventEntry{ - Flags: entry.Flags, - Key: entry.Key, - Value: entry.Value, - } - } - // event matches filter, so record it cev := &CollectedEvent{ - Entries: entries, + Entries: ev.Entries, EmitterAddr: addr, EventIdx: evIdx, Reverted: revert, diff --git a/chain/events/filter/event_test.go b/chain/events/filter/event_test.go index 80c4c7fc0..329573bc1 100644 --- a/chain/events/filter/event_test.go +++ b/chain/events/filter/event_test.go @@ -287,6 +287,7 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event { ev.Entries = append(ev.Entries, types.EventEntry{ Flags: 0x01, Key: in.k, + Codec: cid.Raw, Value: in.v, }) } @@ -295,6 +296,7 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event { ev.Entries = append(ev.Entries, types.EventEntry{ Flags: 0x00, Key: in.k, + Codec: cid.Raw, Value: in.v, }) } diff --git a/chain/events/filter/index.go b/chain/events/filter/index.go index 1b69dfd10..ab4e24493 100644 --- a/chain/events/filter/index.go +++ b/chain/events/filter/index.go @@ -47,6 +47,7 @@ var ddls = []string{ indexed INTEGER NOT NULL, flags BLOB NOT NULL, key TEXT NOT NULL, + codec INTEGER, value BLOB NOT NULL )`, @@ -67,8 +68,8 @@ const ( VALUES(?, ?, ?, ?, ?, ?, ?, ?)` insertEntry = `INSERT OR IGNORE INTO event_entry - (event_id, indexed, flags, key, value) - VALUES(?, ?, ?, ?, ?)` + (event_id, indexed, flags, key, codec, value) + VALUES(?, ?, ?, ?, ?, ?)` ) type EventIndex struct { @@ -194,6 +195,7 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever isIndexedValue(entry.Flags), // indexed []byte{entry.Flags}, // flags entry.Key, // key + entry.Codec, // codec entry.Value, // value ) if err != nil { @@ -251,7 +253,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { subclauses := []string{} for _, val := range vals { subclauses = append(subclauses, fmt.Sprintf("%s.value=?", joinAlias)) - values = append(values, trimLeadingZeros(val)) + values = append(values, val) } clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")") } @@ -270,6 +272,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { event.reverted, event_entry.flags, event_entry.key, + event_entry.codec, event_entry.value FROM event JOIN event_entry ON event.id=event_entry.event_id` @@ -319,6 +322,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { reverted bool flags []byte key string + codec uint64 value []byte } @@ -334,6 +338,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { &row.reverted, &row.flags, &row.key, + &row.codec, &row.value, ); err != nil { return xerrors.Errorf("read prefill row: %w", err) @@ -378,6 +383,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { ce.Entries = append(ce.Entries, types.EventEntry{ Flags: row.flags[0], Key: row.key, + Codec: row.codec, Value: row.value, }) @@ -398,12 +404,3 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { return nil } - -func trimLeadingZeros(b []byte) []byte { - for i := range b { - if b[i] != 0 { - return b[i:] - } - } - return []byte{} -} diff --git a/chain/messagesigner/messagesigner.go b/chain/messagesigner/messagesigner.go index 84dd6d0aa..cd31a3b73 100644 --- a/chain/messagesigner/messagesigner.go +++ b/chain/messagesigner/messagesigner.go @@ -13,13 +13,11 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" - "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/node/modules/dtypes" ) @@ -69,11 +67,7 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message, sp // Sign the message with the nonce msg.Nonce = nonce - keyInfo, err := ms.wallet.WalletExport(ctx, msg.From) - if err != nil { - return nil, err - } - sb, err := SigningBytes(msg, key.ActSigType(keyInfo.Type)) + sb, err := SigningBytes(msg, msg.From.Protocol()) if err != nil { return nil, err } @@ -200,8 +194,8 @@ func (ms *MessageSigner) dstoreKey(addr address.Address) datastore.Key { return datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()}) } -func SigningBytes(msg *types.Message, sigType crypto.SigType) ([]byte, error) { - if sigType == crypto.SigTypeDelegated { +func SigningBytes(msg *types.Message, sigType address.Protocol) ([]byte, error) { + if sigType == address.Delegated { txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msg) if err != nil { return nil, xerrors.Errorf("failed to reconstruct eth transaction: %w", err) diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 61be26e56..ea2758705 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -44,12 +44,12 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. msg.Value = types.NewInt(0) } - return sm.callInternal(ctx, msg, nil, ts, cid.Undef, sm.GetNetworkVersion, false) + return sm.callInternal(ctx, msg, nil, ts, cid.Undef, sm.GetNetworkVersion, false, false) } // CallWithGas calculates the state for a given tipset, and then applies the given message on top of that state. func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet) (*api.InvocResult, error) { - return sm.callInternal(ctx, msg, priorMsgs, ts, cid.Undef, sm.GetNetworkVersion, true) + return sm.callInternal(ctx, msg, priorMsgs, ts, cid.Undef, sm.GetNetworkVersion, true, true) } // CallAtStateAndVersion allows you to specify a message to execute on the given stateCid and network version. @@ -61,13 +61,13 @@ func (sm *StateManager) CallAtStateAndVersion(ctx context.Context, msg *types.Me return v } - return sm.callInternal(ctx, msg, nil, nil, stateCid, nvGetter, true) + return sm.callInternal(ctx, msg, nil, nil, stateCid, nvGetter, true, false) } // - If no tipset is specified, the first tipset without an expensive migration or one in its parent is used. // - If executing a message at a given tipset or its parent would trigger an expensive migration, the call will // fail with ErrExpensiveFork. -func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet, stateCid cid.Cid, nvGetter rand.NetworkVersionGetter, checkGas bool) (*api.InvocResult, error) { +func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, priorMsgs []types.ChainMsg, ts *types.TipSet, stateCid cid.Cid, nvGetter rand.NetworkVersionGetter, checkGas, applyTsMessages bool) (*api.InvocResult, error) { ctx, span := trace.StartSpan(ctx, "statemanager.callInternal") defer span.End() @@ -107,22 +107,18 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr } } - var vmHeight abi.ChainEpoch - if checkGas { - // Since we're simulating a future message, pretend we're applying it in the "next" tipset - vmHeight = ts.Height() + 1 - if stateCid == cid.Undef { - stateCid, _, err = sm.TipSetState(ctx, ts) - if err != nil { - return nil, xerrors.Errorf("computing tipset state: %w", err) - } - } - } else { - // If we're not checking gas, we don't want to have to execute the tipset like above. This saves a lot of computation time - vmHeight = pts.Height() + 1 - if stateCid == cid.Undef { - stateCid = ts.ParentState() + // Unless executing on a specific state cid, apply all the messages from the current tipset + // first. Unfortunately, we can't just execute the tipset, because that will run cron. We + // don't want to apply miner messages after cron runs in a given epoch. + if stateCid == cid.Undef { + stateCid = ts.ParentState() + } + if applyTsMessages { + tsMsgs, err := sm.cs.MessagesForTipset(ctx, ts) + if err != nil { + return nil, xerrors.Errorf("failed to lookup messages for parent tipset: %w", err) } + priorMsgs = append(tsMsgs, priorMsgs...) } // Technically, the tipset we're passing in here should be ts+1, but that may not exist. @@ -142,14 +138,14 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr buffStore := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync()) vmopt := &vm.VMOpts{ StateBase: stateCid, - Epoch: vmHeight, + Epoch: ts.Height(), Timestamp: ts.MinTimestamp(), Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, nvGetter), Bstore: buffStore, Actors: sm.tsExec.NewActorRegistry(), Syscalls: sm.Syscalls, CircSupplyCalc: sm.GetVMCirculatingSupply, - NetworkVersion: nvGetter(ctx, vmHeight), + NetworkVersion: nvGetter(ctx, ts.Height()), BaseFee: ts.Blocks()[0].ParentBaseFee, LookbackState: LookbackStateGetterForTipset(sm, ts), TipSetGetter: TipSetGetterForTipset(sm.cs, ts), diff --git a/chain/store/messages.go b/chain/store/messages.go index efc41bfc1..5ac62d394 100644 --- a/chain/store/messages.go +++ b/chain/store/messages.go @@ -256,6 +256,20 @@ func (cs *ChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader return blsmsgs, secpkmsgs, nil } +func (cs *ChainStore) SecpkMessagesForBlock(ctx context.Context, b *types.BlockHeader) ([]*types.SignedMessage, error) { + _, secpkcids, err := cs.ReadMsgMetaCids(ctx, b.Messages) + if err != nil { + return nil, err + } + + secpkmsgs, err := cs.LoadSignedMessagesFromCids(ctx, secpkcids) + if err != nil { + return nil, xerrors.Errorf("loading secpk messages for block: %w", err) + } + + return secpkmsgs, nil +} + func (cs *ChainStore) GetParentReceipt(ctx context.Context, b *types.BlockHeader, i int) (*types.MessageReceipt, error) { // block headers use adt0, for now. a, err := blockadt.AsArray(cs.ActorStore(ctx), b.ParentMessageReceipts) diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 709f7dd88..314b2be6c 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -1943,7 +1943,7 @@ func (t *Event) UnmarshalCBOR(r io.Reader) (err error) { return nil } -var lengthBufEventEntry = []byte{131} +var lengthBufEventEntry = []byte{132} func (t *EventEntry) MarshalCBOR(w io.Writer) error { if t == nil { @@ -1974,6 +1974,12 @@ func (t *EventEntry) MarshalCBOR(w io.Writer) error { return err } + // t.Codec (uint64) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Codec)); 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") @@ -2008,7 +2014,7 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) { return fmt.Errorf("cbor input should be of type array") } - if extra != 3 { + if extra != 4 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -2035,6 +2041,20 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) { t.Key = string(sval) } + // t.Codec (uint64) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Codec = uint64(extra) + + } // t.Value ([]uint8) (slice) maj, extra, err = cr.ReadHeader() diff --git a/chain/types/ethtypes/eth_transactions.go b/chain/types/ethtypes/eth_transactions.go index 9f9df2381..7c065928e 100644 --- a/chain/types/ethtypes/eth_transactions.go +++ b/chain/types/ethtypes/eth_transactions.go @@ -37,7 +37,8 @@ type EthTx struct { Gas EthUint64 `json:"gas"` MaxFeePerGas EthBigInt `json:"maxFeePerGas"` MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"` - V EthBigInt `json:"v"` + AccessList []EthHash `json:"accessList"` + V EthBigInt `json:"yParity"` R EthBigInt `json:"r"` S EthBigInt `json:"s"` } @@ -86,6 +87,7 @@ func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) { Gas: EthUint64(txArgs.GasLimit), MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas), MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas), + AccessList: []EthHash{}, V: v, R: r, S: s, @@ -115,41 +117,29 @@ func EthTxArgsFromUnsignedEthMessage(msg *types.Message) (EthTxArgs, error) { default: return EthTxArgs{}, fmt.Errorf("unsupported EAM method") } - } else { + } else if msg.Method == builtintypes.MethodsEVM.InvokeContract { 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) - } - + if len(msg.Params) > 0 { params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) if err != nil { return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err) } } + } else { + return EthTxArgs{}, + xerrors.Errorf("invalid methodnum %d: only allowed method is InvokeContract(%d)", + msg.Method, builtintypes.MethodsEVM.InvokeContract) } if paramsReader.Len() != 0 { return EthTxArgs{}, xerrors.Errorf("extra data found in params") } - if len(params) == 0 && msg.Method != builtintypes.MethodSend { - // Otherwise, we don't get a guaranteed round-trip. - return EthTxArgs{}, xerrors.Errorf("msgs with empty parameters from an eth-account must be Sends (MethodNum: %d)", msg.Method) - } - return EthTxArgs{ ChainID: build.Eip155ChainId, Nonce: int(msg.Nonce), @@ -168,9 +158,9 @@ func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*types.Message, er } var err error - method := builtintypes.MethodSend var params []byte var to address.Address + method := builtintypes.MethodsEVM.InvokeContract // nil indicates the EAM, only CreateExternal is allowed if tx.To == nil { to = builtintypes.EthereumAddressManagerActorAddr @@ -190,18 +180,11 @@ func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*types.Message, er 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 + if len(tx.Input) > 0 { 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() } } diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index d003e5ed2..1539a638b 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -25,13 +25,6 @@ import ( "github.com/filecoin-project/lotus/lib/must" ) -var ( - EthTopic1 = "t1" - EthTopic2 = "t2" - EthTopic3 = "t3" - EthTopic4 = "t4" -) - var ErrInvalidAddress = errors.New("invalid Filecoin Eth address") type EthUint64 uint64 @@ -40,18 +33,29 @@ func (e EthUint64) MarshalJSON() ([]byte, error) { return json.Marshal(e.Hex()) } +// UnmarshalJSON should be able to parse these types of input: +// 1. a JSON string containing a hex-encoded uint64 starting with 0x +// 2. a JSON string containing an uint64 in decimal +// 3. a string containing an uint64 in decimal func (e *EthUint64) UnmarshalJSON(b []byte) error { var s string - if err := json.Unmarshal(b, &s); err != nil { - return err + if err := json.Unmarshal(b, &s); err == nil { + base := 10 + if strings.HasPrefix(s, "0x") { + base = 16 + } + parsedInt, err := strconv.ParseUint(strings.Replace(s, "0x", "", -1), base, 64) + if err != nil { + return err + } + eint := EthUint64(parsedInt) + *e = eint + return nil + } else if eint, err := strconv.ParseUint(string(b), 10, 64); err == nil { + *e = EthUint64(eint) + return nil } - parsedInt, err := strconv.ParseUint(strings.Replace(s, "0x", "", -1), 16, 64) - if err != nil { - return err - } - eint := EthUint64(parsedInt) - *e = eint - return nil + return fmt.Errorf("cannot interpret %s as a hex-encoded uint64, or a number", string(b)) } func EthUint64FromHex(s string) (EthUint64, error) { @@ -155,8 +159,11 @@ type EthBlock struct { Uncles []EthHash `json:"uncles"` } +const EthBloomSize = 2048 + var ( - EmptyEthBloom = [256]byte{} + EmptyEthBloom = [EthBloomSize / 8]byte{} + FullEthBloom = [EthBloomSize / 8]byte{} EmptyEthHash = EthHash{} EmptyUncleHash = must.One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array EmptyRootHash = must.One(ParseEthHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) // Keccak-256 hash of the RLP of null @@ -164,6 +171,12 @@ var ( EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} ) +func init() { + for i := range FullEthBloom { + FullEthBloom[i] = 0xff + } +} + func NewEthBlock(hasTransactions bool) EthBlock { b := EthBlock{ Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles. @@ -171,7 +184,7 @@ func NewEthBlock(hasTransactions bool) EthBlock { TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions. ReceiptsRoot: EmptyEthHash, Difficulty: EmptyEthInt, - LogsBloom: EmptyEthBloom[:], + LogsBloom: FullEthBloom[:], Extradata: []byte{}, MixHash: EmptyEthHash, Nonce: EmptyEthNonce, @@ -404,6 +417,10 @@ func DecodeHexString(s string) ([]byte, error) { return b, nil } +func DecodeHexStringTrimSpace(s string) ([]byte, error) { + return DecodeHexString(strings.TrimSpace(s)) +} + func handleHexStringPrefix(s string) string { // Strip the leading 0x or 0X prefix since hex.DecodeString does not support it. if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { @@ -440,6 +457,17 @@ func EthHashFromTxBytes(b []byte) EthHash { return ethHash } +func EthBloomSet(f EthBytes, data []byte) { + hasher := sha3.NewLegacyKeccak256() + hasher.Write(data) + hash := hasher.Sum(nil) + + for i := 0; i < 3; i++ { + n := binary.BigEndian.Uint16(hash[i*2:]) % EthBloomSize + f[(EthBloomSize/8)-(n/8)-1] |= 1 << (n % 8) + } +} + type EthFeeHistory struct { OldestBlock EthUint64 `json:"oldestBlock"` BaseFeePerGas []EthBigInt `json:"baseFeePerGas"` @@ -602,7 +630,7 @@ type EthLog struct { Data EthBytes `json:"data"` // List of topics associated with the event log. - Topics []EthBytes `json:"topics"` + Topics []EthHash `json:"topics"` // Following fields are derived from the transaction containing the log @@ -702,3 +730,45 @@ func GetContractEthAddressFromCode(sender EthAddress, salt [32]byte, initcode [] return ethAddr, nil } + +// EthFeeHistoryParams handles raw jsonrpc params for eth_feeHistory +type EthFeeHistoryParams struct { + BlkCount EthUint64 + NewestBlkNum string + RewardPercentiles *[]float64 +} + +func (e *EthFeeHistoryParams) UnmarshalJSON(b []byte) error { + var params []json.RawMessage + err := json.Unmarshal(b, ¶ms) + if err != nil { + return err + } + switch len(params) { + case 3: + err = json.Unmarshal(params[2], &e.RewardPercentiles) + if err != nil { + return err + } + fallthrough + case 2: + err = json.Unmarshal(params[1], &e.NewestBlkNum) + if err != nil { + return err + } + err = json.Unmarshal(params[0], &e.BlkCount) + if err != nil { + return err + } + default: + return xerrors.Errorf("expected 2 or 3 params, got %d", len(params)) + } + return nil +} + +func (e EthFeeHistoryParams) MarshalJSON() ([]byte, error) { + if e.RewardPercentiles != nil { + return json.Marshal([]interface{}{e.BlkCount, e.NewestBlkNum, e.RewardPercentiles}) + } + return json.Marshal([]interface{}{e.BlkCount, e.NewestBlkNum}) +} diff --git a/chain/types/ethtypes/eth_types_test.go b/chain/types/ethtypes/eth_types_test.go index e42d2bdc3..118fbc901 100644 --- a/chain/types/ethtypes/eth_types_test.go +++ b/chain/types/ethtypes/eth_types_test.go @@ -36,13 +36,19 @@ func TestEthIntUnmarshalJSON(t *testing.T) { {[]byte("\"0x0\""), EthUint64(0)}, {[]byte("\"0x41\""), EthUint64(65)}, {[]byte("\"0x400\""), EthUint64(1024)}, + {[]byte("\"0\""), EthUint64(0)}, + {[]byte("\"41\""), EthUint64(41)}, + {[]byte("\"400\""), EthUint64(400)}, + {[]byte("0"), EthUint64(0)}, + {[]byte("100"), EthUint64(100)}, + {[]byte("1024"), 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) + require.Equal(t, tc.Output, i) } } @@ -216,7 +222,7 @@ func TestEthFilterResultMarshalJSON(t *testing.T) { TransactionHash: hash1, BlockHash: hash2, BlockNumber: 53, - Topics: []EthBytes{hash1[:]}, + Topics: []EthHash{hash1}, Data: EthBytes(hash1[:]), Address: addr, } diff --git a/chain/types/event.go b/chain/types/event.go index 20c6fd852..91b0e95d3 100644 --- a/chain/types/event.go +++ b/chain/types/event.go @@ -30,7 +30,10 @@ type EventEntry struct { // The key of this event entry Key string - // Any DAG-CBOR encodeable type. + // The event value's codec + Codec uint64 + + // The event value Value []byte } diff --git a/chain/vm/gas.go b/chain/vm/gas.go index c9007d3f1..cb0c5def9 100644 --- a/chain/vm/gas.go +++ b/chain/vm/gas.go @@ -213,6 +213,16 @@ var Prices = map[abi.ChainEpoch]Pricelist{ verifyReplicaUpdate: 36316136, }, + build.UpgradeHyggeHeight: &pricelistV0{ + computeGasMulti: 1, + storageGasMulti: 1300, // only applies to messages/return values. + + onChainMessageComputeBase: 38863 + 475000, // includes the actor update cost + onChainMessageStorageBase: 36, + onChainMessageStoragePerByte: 1, + + onChainReturnValuePerByte: 1, + }, } // PricelistByEpoch finds the latest prices for the given epoch diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 2dd1f37e6..cea17f61d 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -291,7 +291,7 @@ func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{}, um := actInfo.vmActor.State() if um == nil { - if act.Code != EmptyObjectCid { + if act.Head != EmptyObjectCid { return nil, xerrors.Errorf("actor with code %s should only have empty object (%s) as its Head, instead has %s", act.Code, EmptyObjectCid, act.Head) } diff --git a/cli/evm.go b/cli/evm.go index 1c02f92b4..2169a3486 100644 --- a/cli/evm.go +++ b/cli/evm.go @@ -107,7 +107,7 @@ var EvmCallSimulateCmd = &cli.Command{ return err } - params, err := ethtypes.DecodeHexString(cctx.Args().Get(2)) + params, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(2)) if err != nil { return err } @@ -151,7 +151,7 @@ var EvmGetContractAddress = &cli.Command{ return err } - salt, err := ethtypes.DecodeHexString(cctx.Args().Get(1)) + salt, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1)) if err != nil { return xerrors.Errorf("Could not decode salt: %w", err) } @@ -170,7 +170,7 @@ var EvmGetContractAddress = &cli.Command{ return err } - contract, err := ethtypes.DecodeHexString(string(contractHex)) + contract, err := ethtypes.DecodeHexStringTrimSpace(string(contractHex)) if err != nil { return xerrors.Errorf("Could not decode contract file: %w", err) } @@ -219,7 +219,7 @@ var EvmDeployCmd = &cli.Command{ return xerrors.Errorf("failed to read contract: %w", err) } if cctx.Bool("hex") { - contract, err = ethtypes.DecodeHexString(string(contract)) + contract, err = ethtypes.DecodeHexStringTrimSpace(string(contract)) if err != nil { return xerrors.Errorf("failed to decode contract: %w", err) } @@ -341,7 +341,7 @@ var EvmInvokeCmd = &cli.Command{ } var calldata []byte - calldata, err = ethtypes.DecodeHexString(cctx.Args().Get(1)) + calldata, err = ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1)) if err != nil { return xerrors.Errorf("decoding hex input data: %w", err) } diff --git a/cli/send.go b/cli/send.go index 3e390584d..e18aa544e 100644 --- a/cli/send.go +++ b/cli/send.go @@ -117,6 +117,17 @@ var sendCmd = &cli.Command{ params.From = faddr } + if params.From.Protocol() == address.Delegated { + if !(params.To.Protocol() == address.ID || params.To.Protocol() == address.Delegated) { + api := srv.FullNodeAPI() + // Resolve id addr if possible. + params.To, err = api.StateLookupID(ctx, params.To, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("f4 addresses can only send to other f4 or id addresses. could not find id address for %s", params.To.String()) + } + } + } + if cctx.IsSet("gas-premium") { gp, err := types.BigFromString(cctx.String("gas-premium")) if err != nil { diff --git a/cmd/lotus-shed/balances.go b/cmd/lotus-shed/balances.go index d678c7977..bd3476ea8 100644 --- a/cmd/lotus-shed/balances.go +++ b/cmd/lotus-shed/balances.go @@ -455,8 +455,9 @@ var chainBalanceStateCmd = &cli.Command{ Description: "Produces a csv file of all account balances from a given stateroot", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "miner-info", @@ -678,8 +679,9 @@ var chainPledgeCmd = &cli.Command{ Description: "Calculate sector pledge numbers", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, ArgsUsage: "[stateroot epoch]", diff --git a/cmd/lotus-shed/datastore.go b/cmd/lotus-shed/datastore.go index 5614e34f6..d6b932954 100644 --- a/cmd/lotus-shed/datastore.go +++ b/cmd/lotus-shed/datastore.go @@ -41,6 +41,11 @@ var datastoreListCmd = &cli.Command{ Name: "list", Description: "list datastore keys", Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, &cli.StringFlag{ Name: "repo-type", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", @@ -110,6 +115,11 @@ var datastoreGetCmd = &cli.Command{ Name: "get", Description: "list datastore keys", Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, &cli.StringFlag{ Name: "repo-type", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", @@ -123,7 +133,7 @@ var datastoreGetCmd = &cli.Command{ }, ArgsUsage: "[namespace key]", Action: func(cctx *cli.Context) error { - logging.SetLogLevel("badger", "ERROR") // nolint:errcheck + _ = logging.SetLogLevel("badger", "ERROR") r, err := repo.NewFS(cctx.String("repo")) if err != nil { diff --git a/cmd/lotus-shed/deal-label.go b/cmd/lotus-shed/deal-label.go index 417d13701..2baa751a9 100644 --- a/cmd/lotus-shed/deal-label.go +++ b/cmd/lotus-shed/deal-label.go @@ -24,8 +24,9 @@ var dealLabelCmd = &cli.Command{ Usage: "Scrape state to report on how many deals have non UTF-8 labels", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/diff.go b/cmd/lotus-shed/diff.go index 981dc850c..e29d9ca6d 100644 --- a/cmd/lotus-shed/diff.go +++ b/cmd/lotus-shed/diff.go @@ -33,8 +33,9 @@ var diffMinerStates = &cli.Command{ ArgsUsage: " ", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/export-car.go b/cmd/lotus-shed/export-car.go index 5cb4737ea..e32dbb2cf 100644 --- a/cmd/lotus-shed/export-car.go +++ b/cmd/lotus-shed/export-car.go @@ -35,8 +35,9 @@ var exportCarCmd = &cli.Command{ Description: "Export a car from repo", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, ArgsUsage: "[outfile] [root cid]", diff --git a/cmd/lotus-shed/export.go b/cmd/lotus-shed/export.go index d67fa4493..749aeceb9 100644 --- a/cmd/lotus-shed/export.go +++ b/cmd/lotus-shed/export.go @@ -42,8 +42,9 @@ var exportChainCmd = &cli.Command{ Description: "Export chain from repo (requires node to be offline)", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "tipset", @@ -146,8 +147,9 @@ var exportRawCmd = &cli.Command{ Description: "Export raw blocks from repo (requires node to be offline)", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "car-size", diff --git a/cmd/lotus-shed/fip-0036.go b/cmd/lotus-shed/fip-0036.go index 485302b9b..1929eb4dd 100644 --- a/cmd/lotus-shed/fip-0036.go +++ b/cmd/lotus-shed/fip-0036.go @@ -58,12 +58,6 @@ var fip36PollCmd = &cli.Command{ Name: "fip36poll", Usage: "Process the FIP0036 FilPoll result", ArgsUsage: "[state root, votes]", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", - }, - }, Subcommands: []*cli.Command{ finalResultCmd, }, @@ -75,8 +69,9 @@ var finalResultCmd = &cli.Command{ ArgsUsage: "[state root] [height] [votes json]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, diff --git a/cmd/lotus-shed/gas-estimation.go b/cmd/lotus-shed/gas-estimation.go index 26c4663bf..6a16770f1 100644 --- a/cmd/lotus-shed/gas-estimation.go +++ b/cmd/lotus-shed/gas-estimation.go @@ -43,8 +43,9 @@ var gasTraceCmd = &cli.Command{ ArgsUsage: "[migratedStateRootCid networkVersion messageCid]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { @@ -147,8 +148,9 @@ var replayOfflineCmd = &cli.Command{ ArgsUsage: "[messageCid]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.Int64Flag{ Name: "lookback-limit", diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index 4c636a3af..43f3fc3d3 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -19,6 +19,13 @@ import ( var importCarCmd = &cli.Command{ Name: "import-car", Description: "Import a car file into node chain blockstore", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { @@ -96,6 +103,13 @@ var importCarCmd = &cli.Command{ var importObjectCmd = &cli.Command{ Name: "import-obj", Usage: "import a raw ipld object into your datastore", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { diff --git a/cmd/lotus-shed/invariants.go b/cmd/lotus-shed/invariants.go index 9798d111a..08b015bf1 100644 --- a/cmd/lotus-shed/invariants.go +++ b/cmd/lotus-shed/invariants.go @@ -36,8 +36,9 @@ var invariantsCmd = &cli.Command{ ArgsUsage: "[StateRootCid, height]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index 38f5ee6fe..1c322f7d6 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -146,9 +146,14 @@ var keyinfoImportCmd = &cli.Command{ Examples env LOTUS_PATH=/var/lib/lotus lotus-shed keyinfo import libp2p-host.keyinfo`, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { - flagRepo := cctx.String("repo") - var input io.Reader if cctx.NArg() == 0 { input = os.Stdin @@ -177,7 +182,7 @@ var keyinfoImportCmd = &cli.Command{ return err } - fsrepo, err := repo.NewFS(flagRepo) + fsrepo, err := repo.NewFS(cctx.String("repo")) if err != nil { return err } diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 19072dd71..a12fa801f 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "os" logging "github.com/ipfs/go-log/v2" @@ -91,19 +90,6 @@ func main() { Version: build.UserVersion(), Commands: local, Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"LOTUS_PATH"}, - Hidden: true, - Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME - }, - &cli.StringFlag{ - Name: "miner-repo", - Aliases: []string{"storagerepo"}, - EnvVars: []string{"LOTUS_MINER_PATH", "LOTUS_STORAGE_PATH"}, - Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME - Usage: fmt.Sprintf("Specify miner repo path. flag storagerepo and env LOTUS_STORAGE_PATH are DEPRECATION, will REMOVE SOON"), - }, &cli.StringFlag{ Name: "log-level", Value: "info", diff --git a/cmd/lotus-shed/market.go b/cmd/lotus-shed/market.go index 0c5e7c81d..6d86c90b9 100644 --- a/cmd/lotus-shed/market.go +++ b/cmd/lotus-shed/market.go @@ -124,8 +124,9 @@ var marketExportDatastoreCmd = &cli.Command{ Description: "export markets datastore key/values to a file", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Usage: "path to the repo", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "backup-dir", @@ -241,8 +242,9 @@ var marketImportDatastoreCmd = &cli.Command{ Description: "import markets datastore key/values from a backup file", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Usage: "path to the repo", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "backup-path", diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go index e305ba7e1..bcbf3d732 100644 --- a/cmd/lotus-shed/migrations.go +++ b/cmd/lotus-shed/migrations.go @@ -55,8 +55,9 @@ var migrationsCmd = &cli.Command{ ArgsUsage: "[new network version, block to look back from]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "skip-pre-migration", diff --git a/cmd/lotus-shed/miner-peerid.go b/cmd/lotus-shed/miner-peerid.go index e43063797..fdf8dae8d 100644 --- a/cmd/lotus-shed/miner-peerid.go +++ b/cmd/lotus-shed/miner-peerid.go @@ -26,10 +26,12 @@ import ( var minerPeeridCmd = &cli.Command{ Name: "miner-peerid", - Usage: "Scrape state to find a miner based on peerid", Flags: []cli.Flag{ + Usage: "Scrape state to find a miner based on peerid", + Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/miner-types.go b/cmd/lotus-shed/miner-types.go index 822d037aa..15e5db265 100644 --- a/cmd/lotus-shed/miner-types.go +++ b/cmd/lotus-shed/miner-types.go @@ -28,10 +28,12 @@ import ( var minerTypesCmd = &cli.Command{ Name: "miner-types", - Usage: "Scrape state to report on how many miners of each WindowPoStProofType exist", Flags: []cli.Flag{ + Usage: "Scrape state to report on how many miners of each WindowPoStProofType exist", + Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/msig.go b/cmd/lotus-shed/msig.go index ccc932c93..96ba91219 100644 --- a/cmd/lotus-shed/msig.go +++ b/cmd/lotus-shed/msig.go @@ -43,8 +43,9 @@ var multisigGetAllCmd = &cli.Command{ ArgsUsage: "[state root]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/nonce-fix.go b/cmd/lotus-shed/nonce-fix.go index d69c8a48d..d68f22e0b 100644 --- a/cmd/lotus-shed/nonce-fix.go +++ b/cmd/lotus-shed/nonce-fix.go @@ -17,12 +17,6 @@ import ( var noncefix = &cli.Command{ Name: "noncefix", Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"LOTUS_PATH"}, - Hidden: true, - Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME - }, &cli.Uint64Flag{ Name: "start", }, diff --git a/cmd/lotus-shed/pruning.go b/cmd/lotus-shed/pruning.go index 275f3bc0a..1b6553057 100644 --- a/cmd/lotus-shed/pruning.go +++ b/cmd/lotus-shed/pruning.go @@ -86,8 +86,9 @@ var stateTreePruneCmd = &cli.Command{ Description: "Deletes old state root data from local chainstore", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.Int64Flag{ Name: "keep-from-lookback", diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index e8c45a0c5..348f2e36d 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -39,8 +39,9 @@ var splitstoreRollbackCmd = &cli.Command{ Description: "rollbacks a splitstore installation", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "gc-coldstore", @@ -129,8 +130,9 @@ var splitstoreClearCmd = &cli.Command{ Description: "clears a splitstore installation for restart from snapshot", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "keys-only", diff --git a/cmd/lotus-shed/terminations.go b/cmd/lotus-shed/terminations.go index c5f35995a..c9e3d26bb 100644 --- a/cmd/lotus-shed/terminations.go +++ b/cmd/lotus-shed/terminations.go @@ -33,8 +33,9 @@ var terminationsCmd = &cli.Command{ ArgsUsage: "[block to look back from] [lookback period (epochs)]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 5ec108347..11466ee1b 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -644,6 +644,7 @@ Response: { "Flags": 7, "Key": "string value", + "Codec": 42, "Value": "Ynl0ZSBhcnJheQ==" } ] @@ -2331,11 +2332,7 @@ Perms: read Inputs: ```json [ - "0x5", - "string value", - [ - 12.3 - ] + "Bw==" ] ``` @@ -2643,7 +2640,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } @@ -2679,7 +2679,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } @@ -2714,7 +2717,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } @@ -2784,7 +2790,7 @@ Response: "address": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "data": "0x07", "topics": [ - "0x07" + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ], "removed": true, "logIndex": "0x5", diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 0c792ee1d..4c503e5e2 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 0c792ee1d1f062377033d7d37442d18f765be467 +Subproject commit 4c503e5e2291b5d541f89d982d975e7994536a54 diff --git a/extern/test-vectors b/extern/test-vectors index d9a75a787..28b0c45ea 160000 --- a/extern/test-vectors +++ b/extern/test-vectors @@ -1 +1 @@ -Subproject commit d9a75a7873aee0db28b87e3970d2ea16a2f37c6a +Subproject commit 28b0c45eab4c302864af0aeaaff813625cfafe97 diff --git a/gateway/node.go b/gateway/node.go index 29f9579f7..87aa32a19 100644 --- a/gateway/node.go +++ b/gateway/node.go @@ -108,7 +108,7 @@ type TargetAPI interface { 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) + EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (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) diff --git a/gateway/proxy_eth.go b/gateway/proxy_eth.go index 40b68f500..838a9ba3f 100644 --- a/gateway/proxy_eth.go +++ b/gateway/proxy_eth.go @@ -294,20 +294,25 @@ func (gw *Node) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) { var EthFeeHistoryMaxBlockCount = 128 // this seems to be expensive; todo: figure out what is a good number that works with everything -func (gw *Node) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) { +func (gw *Node) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { + params, err := jsonrpc.DecodeParams[ethtypes.EthFeeHistoryParams](p) + if err != nil { + return ethtypes.EthFeeHistory{}, xerrors.Errorf("decoding params: %w", err) + } + if err := gw.limit(ctx, stateRateLimitTokens); err != nil { return ethtypes.EthFeeHistory{}, err } - if err := gw.checkBlkParam(ctx, newestBlk); err != nil { + if err := gw.checkBlkParam(ctx, params.NewestBlkNum); err != nil { return ethtypes.EthFeeHistory{}, err } - if blkCount > ethtypes.EthUint64(EthFeeHistoryMaxBlockCount) { + if params.BlkCount > ethtypes.EthUint64(EthFeeHistoryMaxBlockCount) { return ethtypes.EthFeeHistory{}, fmt.Errorf("block count too high") } - return gw.target.EthFeeHistory(ctx, blkCount, newestBlk, rewardPercentiles) + return gw.target.EthFeeHistory(ctx, p) } func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) { diff --git a/gen/bundle/bundle.go b/gen/bundle/bundle.go index c7655157e..d953b99c9 100644 --- a/gen/bundle/bundle.go +++ b/gen/bundle/bundle.go @@ -20,6 +20,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet {{- range . }} { Network: {{printf "%q" .Network}}, Version: {{.Version}}, + {{if .BundleGitTag}} BundleGitTag: {{printf "%q" .BundleGitTag}}, {{end}} ManifestCid: MustParseCid({{printf "%q" .ManifestCid}}), Actors: map[string]cid.Cid { {{- range $name, $cid := .Actors }} @@ -37,6 +38,14 @@ func main() { panic(err) } + // TODO: Re-enable this when we can set the tag for ONLY the appropriate version + // https://github.com/filecoin-project/lotus/issues/10185#issuecomment-1422864836 + //if len(os.Args) > 1 { + // for _, m := range metadata { + // m.BundleGitTag = os.Args[1] + // } + //} + fi, err := os.Create("./build/builtin_actors_gen.go") if err != nil { panic(err) diff --git a/go.mod b/go.mod index 5ab196806..720f2f727 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 - github.com/filecoin-project/go-state-types v0.10.0-alpha-11 + github.com/filecoin-project/go-state-types v0.10.0-rc2 github.com/filecoin-project/go-statemachine v1.0.2 github.com/filecoin-project/go-statestore v0.2.0 github.com/filecoin-project/go-storedcounter v0.1.0 diff --git a/go.sum b/go.sum index f18d295e1..2ade44d4e 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.10.0-alpha-11 h1:lfrbmLXaC3vQk1gQCUwtTuY1U2ANrgDsJ7+VapBjRCo= -github.com/filecoin-project/go-state-types v0.10.0-alpha-11/go.mod h1:aLIas+W8BWAfpLWEPUOGMPBdhcVwoCG4pIQSQk26024= +github.com/filecoin-project/go-state-types v0.10.0-rc2 h1:nl92h86XridAoy0fjvW+8/8/eI0caVSm0fhAnIvtR64= +github.com/filecoin-project/go-state-types v0.10.0-rc2/go.mod h1:aLIas+W8BWAfpLWEPUOGMPBdhcVwoCG4pIQSQk26024= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc= github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= diff --git a/itests/contracts/Create2Factory.hex b/itests/contracts/Create2Factory.hex new file mode 100644 index 000000000..006874306 --- /dev/null +++ b/itests/contracts/Create2Factory.hex @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632b85ba3814610051578063732768dd146100815780637c3e4053146100b2578063bb29998e146100e2575b600080fd5b61006b60048036038101906100669190610473565b610112565b60405161007891906104e1565b60405180910390f35b61009b60048036038101906100969190610473565b61013f565b6040516100a9929190610517565b60405180910390f35b6100cc60048036038101906100c79190610473565b61027e565b6040516100d991906104e1565b60405180910390f35b6100fc60048036038101906100f7919061056c565b6102c0565b60405161010991906104e1565b60405180910390f35b6000816000819055506000806101278461013f565b915091508161013557600080fd5b8092505050919050565b60008060008360405160240161015591906105a8565b6040516020818303038152906040527f7c3e4053000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000803073ffffffffffffffffffffffffffffffffffffffff16836040516101fc9190610634565b600060405180830381855af49150503d8060008114610237576040519150601f19603f3d011682016040523d82523d6000602084013e61023c565b606091505b5091509150811561026e5760008180602001905181019061025d9190610689565b905082819550955050505050610279565b816000945094505050505b915091565b6000818260405161028e9061042b565b61029891906105a8565b8190604051809103906000f59050801580156102b8573d6000803e3d6000fd5b509050919050565b6000808290508073ffffffffffffffffffffffffffffffffffffffff166383197ef06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561030e57600080fd5b505af1158015610322573d6000803e3d6000fd5b5050505060008173ffffffffffffffffffffffffffffffffffffffff166367e404ce6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039791906106cb565b905060006104128373ffffffffffffffffffffffffffffffffffffffff1663bfa0b1336040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d919061070d565b61013f565b509050801561042057600080fd5b819350505050919050565b61028b8061073b83390190565b600080fd5b6000819050919050565b6104508161043d565b811461045b57600080fd5b50565b60008135905061046d81610447565b92915050565b60006020828403121561048957610488610438565b5b60006104978482850161045e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104cb826104a0565b9050919050565b6104db816104c0565b82525050565b60006020820190506104f660008301846104d2565b92915050565b60008115159050919050565b610511816104fc565b82525050565b600060408201905061052c6000830185610508565b61053960208301846104d2565b9392505050565b610549816104c0565b811461055457600080fd5b50565b60008135905061056681610540565b92915050565b60006020828403121561058257610581610438565b5b600061059084828501610557565b91505092915050565b6105a28161043d565b82525050565b60006020820190506105bd6000830184610599565b92915050565b600081519050919050565b600081905092915050565b60005b838110156105f75780820151818401526020810190506105dc565b60008484015250505050565b600061060e826105c3565b61061881856105ce565b93506106288185602086016105d9565b80840191505092915050565b60006106408284610603565b915081905092915050565b6000610656826104a0565b9050919050565b6106668161064b565b811461067157600080fd5b50565b6000815190506106838161065d565b92915050565b60006020828403121561069f5761069e610438565b5b60006106ad84828501610674565b91505092915050565b6000815190506106c581610540565b92915050565b6000602082840312156106e1576106e0610438565b5b60006106ef848285016106b6565b91505092915050565b60008151905061070781610447565b92915050565b60006020828403121561072357610722610438565b5b6000610731848285016106f8565b9150509291505056fe608060405234801561001057600080fd5b5060405161028b38038061028b833981810160405281019061003291906100ba565b326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600181905550506100e7565b600080fd5b6000819050919050565b61009781610084565b81146100a257600080fd5b50565b6000815190506100b48161008e565b92915050565b6000602082840312156100d0576100cf61007f565b5b60006100de848285016100a5565b91505092915050565b610195806100f66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806367e404ce1461004657806383197ef014610064578063bfa0b1331461006e575b600080fd5b61004e61008c565b60405161005b9190610110565b60405180910390f35b61006c6100b0565b005b6100766100c9565b6040516100839190610144565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b60015481565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100fa826100cf565b9050919050565b61010a816100ef565b82525050565b60006020820190506101256000830184610101565b92915050565b6000819050919050565b61013e8161012b565b82525050565b60006020820190506101596000830184610135565b9291505056fea26469706673582212208252a57fdfc00b722b7063f2d28dd8c5a36b469462c89da52bcf17ccdda2de6764736f6c63430008110033a26469706673582212200edf974d1735ee81f671df7e60300ab28168b8cb22cc3e59180ef743c4a526c964736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/Create2Factory.sol b/itests/contracts/Create2Factory.sol new file mode 100644 index 000000000..ffec40822 --- /dev/null +++ b/itests/contracts/Create2Factory.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.17; +contract Create2Factory { + + bytes32 savedSalt; + + // Returns the address of the newly deployed contract + function deploy( + bytes32 _salt + ) public returns (address) { + // This syntax is a newer way to invoke create2 without assembly, you just need to pass salt + // https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2 + savedSalt = _salt; + (bool success, address ret) = deployDelegateCall(_salt); + require(success); + return ret; + } + + function deployDelegateCall( + bytes32 _salt + ) public returns (bool, address) { + bytes memory data = abi.encodeWithSignature("_deploy(bytes32)", _salt); + (bool success, bytes memory returnedData) = address(this).delegatecall(data); + if(success){ + (address ret) = abi.decode(returnedData, (address)); + return (success, ret); + }else{ + return (success, address(0)); + } + } + + function _deploy(bytes32 _salt) public returns (address) { + // https://solidity-by-example.org/app/create1/ + // This syntax is a newer way to invoke create2 without assembly, you just need to pass salt + // https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2 + return address(new SelfDestruct{salt: _salt}(_salt)); + } + + function test(address _address) public returns (address){ + + // run destroy() on _address + SelfDestruct selfDestruct = SelfDestruct(_address); + selfDestruct.destroy(); + + //verify data can still be accessed + address ret = selfDestruct.sender(); + + // attempt and fail to deploy contract using salt + (bool success, ) = deployDelegateCall(selfDestruct.salt()); + require(!success); + + return ret; + } +} + +contract SelfDestruct { + address public sender; + bytes32 public salt; + constructor(bytes32 _salt) { + sender = tx.origin; + salt=_salt; + } + function destroy() public { + selfdestruct(payable(msg.sender)); + } +} + diff --git a/itests/contracts/DeployValueTest.hex b/itests/contracts/DeployValueTest.hex new file mode 100644 index 000000000..535704abf --- /dev/null +++ b/itests/contracts/DeployValueTest.hex @@ -0,0 +1 @@ +60806040523460405161001190610073565b6040518091039082f090508015801561002e573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061007f565b60c78061031683390190565b6102888061008e6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630e3608df146100465780634313b53114610064578063b0d22c6214610082575b600080fd5b61004e6100a0565b60405161005b919061017d565b60405180910390f35b61006c610137565b60405161007991906101d9565b60405180910390f35b61008a61015b565b604051610097919061017d565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166312065fe06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101329190610225565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006007905090565b6000819050919050565b61017781610164565b82525050565b6000602082019050610192600083018461016e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c382610198565b9050919050565b6101d3816101b8565b82525050565b60006020820190506101ee60008301846101ca565b92915050565b600080fd5b61020281610164565b811461020d57600080fd5b50565b60008151905061021f816101f9565b92915050565b60006020828403121561023b5761023a6101f4565b5b600061024984828501610210565b9150509291505056fea2646970667358221220c24abd10dbe58d92bfe62cb351771fcdc45d54241a8ce7085f2a75179c67cd8a64736f6c63430008110033608060405260b5806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806312065fe014602d575b600080fd5b60336047565b604051603e91906066565b60405180910390f35b600047905090565b6000819050919050565b606081604f565b82525050565b6000602082019050607960008301846059565b9291505056fea26469706673582212207123972a300833ee01aebf99e4bdf8ecf9f01c0d3dd776048bd41803c6855c0e64736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/DeployValueTest.sol b/itests/contracts/DeployValueTest.sol new file mode 100644 index 000000000..fe261b014 --- /dev/null +++ b/itests/contracts/DeployValueTest.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.17; + + + +contract DeployValueTest { + address public newContract; + + constructor() payable { + newContract = address(new NewContract{value: msg.value}()); + } + + function getConst() public view returns (uint) { + return 7; + } + + function getNewContractBalance() public view returns (uint) { + return NewContract(newContract).getBalance(); + } +} + +contract NewContract { + constructor() payable { + } + + function getBalance() public view returns (uint) { + return address(this).balance; + } +} diff --git a/itests/contracts/compile.sh b/itests/contracts/compile.sh old mode 100755 new mode 100644 index 4395fdb53..029bff46c --- a/itests/contracts/compile.sh +++ b/itests/contracts/compile.sh @@ -12,7 +12,7 @@ find . -name \*.sol -print0 | #for these contracts we have 2 contracts in the same solidity file #this command grabs the correct bytecode for us -for filename in Constructor TestApp ValueSender ; do +for filename in Constructor TestApp ValueSender Create2Factory DeployValueTest; do echo $filename solc --bin $filename.sol | tail -n5|head -n1 | tr -d "\n" > $filename.hex done diff --git a/itests/eth_account_abstraction_test.go b/itests/eth_account_abstraction_test.go index e6d9723bf..8d92d0a04 100644 --- a/itests/eth_account_abstraction_test.go +++ b/itests/eth_account_abstraction_test.go @@ -24,7 +24,7 @@ import ( "github.com/filecoin-project/lotus/itests/kit" ) -// TestEthAccountAbstraction goes over the account abstraction workflow: +// TestEthAccountAbstraction goes over the placeholder creation and promotion workflow: // - an placeholder is created when it receives a message // - the placeholder turns into an EOA when it sends a message func TestEthAccountAbstraction(t *testing.T) { @@ -67,7 +67,8 @@ func TestEthAccountAbstraction(t *testing.T) { msgFromPlaceholder := &types.Message{ From: placeholderAddress, // self-send because an "eth tx payload" can't be to a filecoin address? - To: placeholderAddress, + To: placeholderAddress, + Method: builtin2.MethodsEVM.InvokeContract, } msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK) require.NoError(t, err) @@ -100,9 +101,10 @@ func TestEthAccountAbstraction(t *testing.T) { // Send another message, it should succeed without any code CID changes msgFromPlaceholder = &types.Message{ - From: placeholderAddress, - To: placeholderAddress, - Nonce: 1, + From: placeholderAddress, + To: placeholderAddress, + Method: builtin2.MethodsEVM.InvokeContract, + Nonce: 1, } msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK) @@ -152,9 +154,10 @@ func TestEthAccountAbstractionFailure(t *testing.T) { // create a placeholder actor at the target address msgCreatePlaceholder := &types.Message{ - From: client.DefaultKey.Address, - To: placeholderAddress, - Value: abi.TokenAmount(types.MustParseFIL("100")), + From: client.DefaultKey.Address, + To: placeholderAddress, + Value: abi.TokenAmount(types.MustParseFIL("100")), + Method: builtin2.MethodsEVM.InvokeContract, } smCreatePlaceholder, err := client.MpoolPushMessage(ctx, msgCreatePlaceholder, nil) require.NoError(t, err) @@ -172,9 +175,10 @@ func TestEthAccountAbstractionFailure(t *testing.T) { // send a message from the placeholder address msgFromPlaceholder := &types.Message{ - From: placeholderAddress, - To: placeholderAddress, - Value: abi.TokenAmount(types.MustParseFIL("20")), + From: placeholderAddress, + To: placeholderAddress, + Value: abi.TokenAmount(types.MustParseFIL("20")), + Method: builtin2.MethodsEVM.InvokeContract, } msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK) require.NoError(t, err) @@ -209,10 +213,11 @@ func TestEthAccountAbstractionFailure(t *testing.T) { // Send a valid message now, it should succeed without any code CID changes msgFromPlaceholder = &types.Message{ - From: placeholderAddress, - To: placeholderAddress, - Nonce: 1, - Value: abi.NewTokenAmount(1), + From: placeholderAddress, + To: placeholderAddress, + Nonce: 1, + Value: abi.NewTokenAmount(1), + Method: builtin2.MethodsEVM.InvokeContract, } msgFromPlaceholder, err = client.GasEstimateMessageGas(ctx, msgFromPlaceholder, nil, types.EmptyTSK) diff --git a/itests/eth_bytecode_test.go b/itests/eth_bytecode_test.go new file mode 100644 index 000000000..4d03a0f6d --- /dev/null +++ b/itests/eth_bytecode_test.go @@ -0,0 +1,74 @@ +package itests + +import ( + "context" + "encoding/hex" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" +) + +// TestGetCode ensures that GetCode returns the correct results for: +// 1. Placeholders. +// 2. Non-existent actors. +// 3. Normal EVM actors. +// 4. Self-destructed EVM actors. +func TestGetCode(t *testing.T) { + kit.QuietMiningLogs() + + blockTime := 100 * time.Millisecond + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blockTime) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + // Accounts should have empty code. + { + // A random eth address should have no code. + _, ethAddr, filAddr := client.EVM().NewAccount() + bytecode, err := client.EVM().EthGetCode(ctx, ethAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + + // send some funds to the account. + kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10)) + + // The code should still be empty, target is now a placeholder. + bytecode, err = client.EVM().EthGetCode(ctx, ethAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + } + + // Check contract code. + { + // install a contract + contractHex, err := os.ReadFile("./contracts/SelfDestruct.hex") + require.NoError(t, err) + contract, err := hex.DecodeString(string(contractHex)) + require.NoError(t, err) + createReturn := client.EVM().DeployContract(ctx, client.DefaultKey.Address, contract) + contractAddr := createReturn.EthAddress + contractFilAddr := *createReturn.RobustAddress + + // The newly deployed contract should not be empty. + bytecode, err := client.EVM().EthGetCode(ctx, contractAddr, "latest") + require.NoError(t, err) + require.NotEmpty(t, bytecode) + + // Destroy it. + _, _, err = client.EVM().InvokeContractByFuncName(ctx, client.DefaultKey.Address, contractFilAddr, "destroy()", nil) + require.NoError(t, err) + + // The code should be empty again. + bytecode, err = client.EVM().EthGetCode(ctx, contractAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + } + +} diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go index b11366465..8a367d6b1 100644 --- a/itests/eth_conformance_test.go +++ b/itests/eth_conformance_test.go @@ -139,8 +139,6 @@ func TestEthOpenRPCConformance(t *testing.T) { require.NoError(t, err) defer closer() - const skipUntilIssue10106 = "Skipped until EthTx is updated, see https://github.com/filecoin-project/lotus/issues/10106" - testCases := []struct { method string variant string // suffix applied to the test name to distinguish different variants of a method call @@ -194,7 +192,7 @@ func TestEthOpenRPCConformance(t *testing.T) { { method: "eth_feeHistory", call: func(a *ethAPIRaw) (json.RawMessage, error) { - return ethapi.EthFeeHistory(context.Background(), ethtypes.EthUint64(2), "", nil) + return ethapi.EthFeeHistory(context.Background(), ethtypes.EthUint64(2), "latest", nil) }, }, @@ -227,7 +225,6 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetBlockByHash(context.Background(), blockHashWithMessage, true) }, - skipReason: skipUntilIssue10106, }, { @@ -236,7 +233,7 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetBlockByNumber(context.Background(), "earliest", true) }, - skipReason: skipUntilIssue10106, + skipReason: "earliest block is not supported", }, { @@ -245,7 +242,6 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetBlockByNumber(context.Background(), "pending", true) }, - skipReason: skipUntilIssue10106, }, { @@ -253,7 +249,6 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetBlockByNumber(context.Background(), blockNumberWithMessage.Hex(), true) }, - skipReason: skipUntilIssue10106, }, { @@ -329,7 +324,7 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetTransactionByBlockHashAndIndex(context.Background(), blockHashWithMessage, ethtypes.EthUint64(0)) }, - skipReason: skipUntilIssue10106, + skipReason: "unimplemented", }, { @@ -337,7 +332,7 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetTransactionByBlockNumberAndIndex(context.Background(), blockNumberWithMessage, ethtypes.EthUint64(0)) }, - skipReason: skipUntilIssue10106, + skipReason: "unimplemented", }, { @@ -345,7 +340,6 @@ func TestEthOpenRPCConformance(t *testing.T) { call: func(a *ethAPIRaw) (json.RawMessage, error) { return ethapi.EthGetTransactionByHash(context.Background(), &messageWithEvents) }, - skipReason: skipUntilIssue10106, }, { diff --git a/itests/eth_deploy_test.go b/itests/eth_deploy_test.go index 98038de7b..bbdadb1d5 100644 --- a/itests/eth_deploy_test.go +++ b/itests/eth_deploy_test.go @@ -11,12 +11,16 @@ import ( "time" "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/manifest" + gstStore "github.com/filecoin-project/go-state-types/store" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/evm" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/itests/kit" @@ -219,4 +223,32 @@ func TestDeployment(t *testing.T) { require.NoError(t, err) client.AssertActorType(ctx, contractAddr, "evm") + + // Check bytecode and bytecode hash match. + contractAct, err := client.StateGetActor(ctx, contractAddr, types.EmptyTSK) + require.NoError(t, err) + + bs := blockstore.NewAPIBlockstore(client) + ctxStore := gstStore.WrapBlockStore(ctx, bs) + + evmSt, err := evm.Load(ctxStore, contractAct) + require.NoError(t, err) + + byteCodeCid, err := evmSt.GetBytecodeCID() + require.NoError(t, err) + + byteCode, err := bs.Get(ctx, byteCodeCid) + require.NoError(t, err) + + byteCodeHashChain, err := evmSt.GetBytecodeHash() + require.NoError(t, err) + + hasher := sha3.NewLegacyKeccak256() + hasher.Write(byteCode.RawData()) + byteCodeHash := hasher.Sum(nil) + require.Equal(t, byteCodeHashChain[:], byteCodeHash) + + byteCodeSt, err := evmSt.GetBytecode() + require.NoError(t, err) + require.Equal(t, byteCode.RawData(), byteCodeSt) } diff --git a/itests/eth_fee_history_test.go b/itests/eth_fee_history_test.go new file mode 100644 index 000000000..9b256c527 --- /dev/null +++ b/itests/eth_fee_history_test.go @@ -0,0 +1,87 @@ +package itests + +import ( + "context" + "encoding/json" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-jsonrpc" + + "github.com/filecoin-project/lotus/chain/types/ethtypes" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/lib/result" +) + +func TestEthFeeHistory(t *testing.T) { + require := require.New(t) + + kit.QuietAllLogsExcept() + + blockTime := 100 * time.Millisecond + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blockTime) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + // Wait for the network to create 20 blocks + <-time.After(20 * blockTime) + + history, err := client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{5, "0x10"}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(6, len(history.BaseFeePerGas)) + require.Equal(5, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{"5", "0x10"}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(6, len(history.BaseFeePerGas)) + require.Equal(5, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{"0x10", "0x12"}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(17, len(history.BaseFeePerGas)) + require.Equal(16, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(18-16+1), history.OldestBlock) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{5, "0x10"}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(6, len(history.BaseFeePerGas)) + require.Equal(5, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{5, "10"}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(6, len(history.BaseFeePerGas)) + require.Equal(5, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{5, "10", &[]float64{0.25, 0.50, 0.75}}), + ).Assert(require.NoError)) + require.NoError(err) + require.Equal(6, len(history.BaseFeePerGas)) + require.Equal(5, len(history.GasUsedRatio)) + require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock) + require.NotNil(history.Reward) + require.Equal(0, len(*history.Reward)) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{1025, "10", &[]float64{0.25, 0.50, 0.75}}), + ).Assert(require.NoError)) + require.Error(err) +} diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index cdaf599ba..9540c5ebe 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -7,6 +7,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math/bits" "os" "sort" "strconv" @@ -16,7 +17,6 @@ import ( "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" - cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -285,33 +285,33 @@ func TestEthNewFilterDefaultSpec(t *testing.T) { expected := []ExpectedEthLog{ { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ - paddedEthBytes([]byte{0x11, 0x11}), - paddedEthBytes([]byte{0x22, 0x22}), - paddedEthBytes([]byte{0x33, 0x33}), - paddedEthBytes([]byte{0x44, 0x44}), + Topics: []ethtypes.EthHash{ + paddedEthHash([]byte{0x11, 0x11}), + paddedEthHash([]byte{0x22, 0x22}), + paddedEthHash([]byte{0x33, 0x33}), + paddedEthHash([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ - paddedEthBytes([]byte{0x11, 0x11}), - paddedEthBytes([]byte{0x22, 0x22}), - paddedEthBytes([]byte{0x33, 0x33}), - paddedEthBytes([]byte{0x44, 0x44}), + Topics: []ethtypes.EthHash{ + paddedEthHash([]byte{0x11, 0x11}), + paddedEthHash([]byte{0x22, 0x22}), + paddedEthHash([]byte{0x33, 0x33}), + paddedEthHash([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ - paddedEthBytes([]byte{0x11, 0x11}), - paddedEthBytes([]byte{0x22, 0x22}), - paddedEthBytes([]byte{0x33, 0x33}), - paddedEthBytes([]byte{0x44, 0x44}), + Topics: []ethtypes.EthHash{ + paddedEthHash([]byte{0x11, 0x11}), + paddedEthHash([]byte{0x22, 0x22}), + paddedEthHash([]byte{0x33, 0x33}), + paddedEthHash([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, } @@ -344,13 +344,13 @@ func TestEthGetLogsBasic(t *testing.T) { expected := []ExpectedEthLog{ { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ - paddedEthBytes([]byte{0x11, 0x11}), - paddedEthBytes([]byte{0x22, 0x22}), - paddedEthBytes([]byte{0x33, 0x33}), - paddedEthBytes([]byte{0x44, 0x44}), + Topics: []ethtypes.EthHash{ + paddedEthHash([]byte{0x11, 0x11}), + paddedEthHash([]byte{0x22, 0x22}), + paddedEthHash([]byte{0x33, 0x33}), + paddedEthHash([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, } @@ -409,13 +409,13 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { for i := range expected { expected[i] = ExpectedEthLog{ Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ - paddedEthBytes([]byte{0x11, 0x11}), - paddedEthBytes([]byte{0x22, 0x22}), - paddedEthBytes([]byte{0x33, 0x33}), - paddedEthBytes([]byte{0x44, 0x44}), + Topics: []ethtypes.EthHash{ + paddedEthHash([]byte{0x11, 0x11}), + paddedEthHash([]byte{0x22, 0x22}), + paddedEthHash([]byte{0x33, 0x33}), + paddedEthHash([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, } } @@ -424,6 +424,51 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { AssertEthLogs(t, elogs, expected, messages) } +func TestTxReceiptBloom(t *testing.T) { + blockTime := 50 * time.Millisecond + client, _, ens := kit.EnsembleMinimal( + t, + kit.MockProofs(), + kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blockTime) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, "contracts/EventMatrix.hex") + + _, ml, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "logEventZeroData()", nil) + require.NoError(t, err) + + th, err := client.EthGetTransactionHashByCid(ctx, ml.Message) + require.NoError(t, err) + require.NotNil(t, th) + + receipt, err := client.EthGetTransactionReceipt(ctx, *th) + require.NoError(t, err) + require.NotNil(t, receipt) + require.Len(t, receipt.Logs, 1) + + // computed by calling EventMatrix/logEventZeroData in remix + // note this only contains topic bits + matchMask := "0x00000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + maskBytes, err := hex.DecodeString(matchMask[2:]) + require.NoError(t, err) + + bitsSet := 0 + for i, maskByte := range maskBytes { + bitsSet += bits.OnesCount8(receipt.LogsBloom[i]) + + if maskByte > 0 { + require.True(t, maskByte&receipt.LogsBloom[i] > 0) + } + } + + // 3 bits from the topic, 3 bits from the address + require.Equal(t, 6, bitsSet) +} + func TestEthGetLogs(t *testing.T) { require := require.New(t) kit.QuietAllLogsExcept("events", "messagepool") @@ -563,19 +608,13 @@ func TestEthSubscribeLogs(t *testing.T) { var elogs []*ethtypes.EthLog for resp := range responseCh { - rlist, ok := resp.Result.([]interface{}) - require.True(ok, "expected subscription result to be []interface{}, but was %T", resp.Result) + rmap, ok := resp.Result.(map[string]interface{}) + require.True(ok, "expected subscription result entry to be map[string]interface{}, but was %T", resp.Result) - for _, rentry := range rlist { - rmap, ok := rentry.(map[string]interface{}) - require.True(ok, "expected subscription result entry to be map[string]interface{}, but was %T", resp.Result) - - elog, err := ParseEthLog(rmap) - require.NoError(err) - - elogs = append(elogs, elog) - } + elog, err := ParseEthLog(rmap) + require.NoError(err) + elogs = append(elogs, elog) } AssertEthLogs(t, elogs, tc.expected, messages) }) @@ -657,10 +696,10 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { distinctHeights[m.ts.Height()] = true expectedByHeight[m.ts.Height()] = append(expectedByHeight[m.ts.Height()], ExpectedEthLog{ Address: addr, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(args[0]), - paddedUint64(args[1]), + uint64EthHash(args[0]), + uint64EthHash(args[1]), }, Data: paddedUint64(args[2]), }) @@ -723,7 +762,7 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { require.True(len(partition3.expected) > 0, "partition should have events") // these are the topics we selected for partitioning earlier - topics := []ethtypes.EthHash{paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])} + topics := []ethtypes.EthHash{kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]} union := func(lists ...[]ExpectedEthLog) []ExpectedEthLog { ret := []ExpectedEthLog{} @@ -911,30 +950,30 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) { expected := []ExpectedEthLog{ { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneData"], }, Data: paddedUint64(1), }, { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexed"], - paddedUint64(2), + uint64EthHash(2), }, }, { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneData"], }, Data: paddedUint64(3), }, { Address: ethContractAddr, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexed"], - paddedUint64(4), + uint64EthHash(4), }, }, } @@ -1325,19 +1364,19 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock return []filterTestCase{ { name: "find all EventZeroData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventZeroData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventZeroData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, @@ -1346,19 +1385,19 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventOneData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneData"], }, Data: packUint64Values(23), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneData"], }, Data: packUint64Values(44), @@ -1367,12 +1406,12 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventTwoData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoData"], }, Data: packUint64Values(555, 666), @@ -1381,12 +1420,12 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventThreeData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeData"], }, Data: packUint64Values(1, 2, 3), @@ -1395,14 +1434,14 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneIndexed events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventOneIndexed"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexed"], - paddedUint64(44), + uint64EthHash(44), }, Data: nil, }, @@ -1410,24 +1449,24 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoIndexed events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventTwoIndexed"]).Filter(), expected: []ExpectedEthLog{ { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexed"], - paddedUint64(44), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(19), }, Data: nil, }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexed"], - paddedUint64(40), - paddedUint64(20), + uint64EthHash(40), + uint64EthHash(20), }, Data: nil, }, @@ -1435,16 +1474,16 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeIndexed events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventThreeIndexed"]).Filter(), expected: []ExpectedEthLog{ { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexed"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: nil, }, @@ -1452,30 +1491,30 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneIndexedWithData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventOneIndexedWithData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(44), + uint64EthHash(44), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(46), + uint64EthHash(46), }, Data: paddedUint64(12), }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(50), + uint64EthHash(50), }, Data: paddedUint64(9), }, @@ -1483,33 +1522,33 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoIndexedWithData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(44), - paddedUint64(27), + uint64EthHash(44), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(27), + uint64EthHash(46), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(14), + uint64EthHash(46), + uint64EthHash(14), }, Data: paddedUint64(19), }, @@ -1517,16 +1556,16 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeIndexedWithData events", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(kit.EventMatrixContract.Ev["EventThreeIndexedWithData"]).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: paddedUint64(12), }, @@ -1535,60 +1574,60 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { name: "find all events with topic2 of 44", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(44))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(uint64EthHash(44)).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexed"], - paddedUint64(44), + uint64EthHash(44), }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexed"], - paddedUint64(44), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(19), }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexed"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: nil, }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(44), + uint64EthHash(44), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(44), - paddedUint64(27), + uint64EthHash(44), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: paddedUint64(12), }, @@ -1596,32 +1635,32 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 46", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(uint64EthHash(46)).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(46), + uint64EthHash(46), }, Data: paddedUint64(12), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(27), + uint64EthHash(46), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(14), + uint64EthHash(46), + uint64EthHash(14), }, Data: paddedUint64(19), }, @@ -1629,14 +1668,14 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 50", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(50))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(uint64EthHash(50)).Filter(), expected: []ExpectedEthLog{ { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(50), + uint64EthHash(50), }, Data: paddedUint64(9), }, @@ -1644,40 +1683,40 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 46 or 50", - spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46)), paddedEthHash(paddedUint64(50))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(uint64EthHash(46), uint64EthHash(50)).Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(46), + uint64EthHash(46), }, Data: paddedUint64(12), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(27), + uint64EthHash(46), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(14), + uint64EthHash(46), + uint64EthHash(14), }, Data: paddedUint64(19), }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(50), + uint64EthHash(50), }, Data: paddedUint64(9), }, @@ -1688,26 +1727,26 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock name: "find all events with topic1 of EventTwoIndexedWithData and topic3 of 27", spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). - Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])). - Topic3OneOf(paddedEthHash(paddedUint64(27))). + Topic1OneOf(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]). + Topic3OneOf(uint64EthHash(27)). Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(44), - paddedUint64(27), + uint64EthHash(44), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(46), - paddedUint64(27), + uint64EthHash(46), + uint64EthHash(27), }, Data: paddedUint64(19), }, @@ -1718,25 +1757,25 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock name: "find all events with topic1 of EventTwoIndexedWithData or EventOneIndexed and topic2 of 44", spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). - Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]), paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexed"])). - Topic2OneOf(paddedEthHash(paddedUint64(44))). + Topic1OneOf((kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]), kit.EventMatrixContract.Ev["EventOneIndexed"]). + Topic2OneOf(uint64EthHash(44)). Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], - paddedUint64(44), - paddedUint64(27), + uint64EthHash(44), + uint64EthHash(27), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexed"], - paddedUint64(44), + uint64EthHash(44), }, Data: nil, }, @@ -1755,35 +1794,35 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo expected: []ExpectedEthLog{ { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexed"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexed"], - paddedUint64(44), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(19), }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(50), + uint64EthHash(50), }, Data: paddedUint64(9), }, @@ -1797,20 +1836,20 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo expected: []ExpectedEthLog{ { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventThreeIndexed"], - paddedUint64(44), - paddedUint64(27), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(27), + uint64EthHash(19), }, Data: nil, }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventTwoIndexed"], - paddedUint64(44), - paddedUint64(19), + uint64EthHash(44), + uint64EthHash(19), }, Data: nil, }, @@ -1822,31 +1861,31 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). AddressOneOf(contract1, contract2). - Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexedWithData"])). + Topic1OneOf(kit.EventMatrixContract.Ev["EventOneIndexedWithData"]). Filter(), expected: []ExpectedEthLog{ { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(44), + uint64EthHash(44), }, Data: paddedUint64(19), }, { Address: contract1, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(46), + uint64EthHash(46), }, Data: paddedUint64(12), }, { Address: contract2, - Topics: []ethtypes.EthBytes{ + Topics: []ethtypes.EthHash{ kit.EventMatrixContract.Ev["EventOneIndexedWithData"], - paddedUint64(50), + uint64EthHash(50), }, Data: paddedUint64(9), }, @@ -1867,21 +1906,22 @@ type ExpectedEthLog struct { Address ethtypes.EthAddress `json:"address"` // List of topics associated with the event log. - Topics []ethtypes.EthBytes `json:"topics"` + Topics []ethtypes.EthHash `json:"topics"` // Data is the value of the event log, excluding topics Data ethtypes.EthBytes `json:"data"` } func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedEthLog, messages map[ethtypes.EthHash]msgInTipset) { + t.Helper() require := require.New(t) t.Logf("got %d ethlogs, wanted %d", len(actual), len(expected)) - formatTopics := func(topics []ethtypes.EthBytes) string { + formatTopics := func(topics []ethtypes.EthHash) string { ss := make([]string, len(topics)) for i := range topics { - ss[i] = fmt.Sprintf("%d:%x", i, topics[i]) + ss[i] = fmt.Sprintf("%d:%s", i, topics[i]) } return strings.Join(ss, ",") } @@ -1918,7 +1958,7 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE } for j := range elog.Topics { - if !bytes.Equal(elog.Topics[j], want.Topics[j]) { + if elog.Topics[j] != want.Topics[j] { continue LoopExpected } } @@ -1943,7 +1983,7 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE buf.WriteString(fmt.Sprintf("event %d\n", i)) buf.WriteString(fmt.Sprintf(" emitter: %v\n", ev.Emitter)) for _, en := range ev.Entries { - buf.WriteString(fmt.Sprintf(" %s=%x\n", en.Key, decodeLogBytes(en.Value))) + buf.WriteString(fmt.Sprintf(" %s=%x\n", en.Key, en.Value)) } } @@ -1966,23 +2006,16 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE func parseEthLogsFromSubscriptionResponses(subResponses []ethtypes.EthSubscriptionResponse) ([]*ethtypes.EthLog, error) { elogs := make([]*ethtypes.EthLog, 0, len(subResponses)) for i := range subResponses { - rlist, ok := subResponses[i].Result.([]interface{}) + rmap, ok := subResponses[i].Result.(map[string]interface{}) if !ok { - return nil, xerrors.Errorf("expected subscription result to be []interface{}, but was %T", subResponses[i].Result) + return nil, xerrors.Errorf("expected subscription result entry to be map[string]interface{}, but was %T", subResponses[i].Result) } - for _, r := range rlist { - rmap, ok := r.(map[string]interface{}) - if !ok { - return nil, xerrors.Errorf("expected subscription result entry to be map[string]interface{}, but was %T", r) - } - - elog, err := ParseEthLog(rmap) - if err != nil { - return nil, err - } - elogs = append(elogs, elog) + elog, err := ParseEthLog(rmap) + if err != nil { + return nil, err } + elogs = append(elogs, elog) } return elogs, nil @@ -2099,7 +2132,7 @@ func ParseEthLog(in map[string]interface{}) (*ethtypes.EthLog, error) { if err != nil { return nil, xerrors.Errorf("%s: %w", k, err) } - el.Topics = append(el.Topics, topic) + el.Topics = append(el.Topics, paddedEthHash(topic)) continue } @@ -2112,7 +2145,7 @@ func ParseEthLog(in map[string]interface{}) (*ethtypes.EthLog, error) { if err != nil { return nil, xerrors.Errorf("%s: %w", k, err) } - el.Topics = append(el.Topics, topic) + el.Topics = append(el.Topics, paddedEthHash(topic)) } } } @@ -2120,22 +2153,18 @@ func ParseEthLog(in map[string]interface{}) (*ethtypes.EthLog, error) { return el, err } -func paddedEthBytes(orig []byte) ethtypes.EthBytes { - needed := 32 - len(orig) - if needed <= 0 { - return orig - } - ret := make([]byte, 32) - copy(ret[needed:], orig) - return ret -} - func paddedUint64(v uint64) ethtypes.EthBytes { buf := make([]byte, 32) binary.BigEndian.PutUint64(buf[24:], v) return buf } +func uint64EthHash(v uint64) ethtypes.EthHash { + var buf ethtypes.EthHash + binary.BigEndian.PutUint64(buf[24:], v) + return buf +} + func paddedEthHash(orig []byte) ethtypes.EthHash { if len(orig) > 32 { panic("exceeds EthHash length") @@ -2167,14 +2196,3 @@ func unpackUint64Values(data []byte) []uint64 { } return vals } - -func decodeLogBytes(orig []byte) []byte { - if len(orig) == 0 { - return orig - } - decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig))) - if err != nil { - return orig - } - return decoded -} diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 68a653ca0..2b2a3a6d3 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -3,10 +3,12 @@ package itests import ( "bytes" "context" + "crypto/rand" "encoding/binary" "encoding/hex" "fmt" "testing" + "time" "github.com/stretchr/testify/require" @@ -16,6 +18,7 @@ import ( "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/manifest" + "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" @@ -57,7 +60,7 @@ func buildInputFromuint64(number uint64) []byte { // recursive delegate calls that fail due to gas limits are currently getting to 229 iterations // before running out of gas func recursiveDelegatecallFail(ctx context.Context, t *testing.T, client *kit.TestFullNode, filename string, count uint64) { - expectedIterationsBeforeFailing := int(228) + expectedIterationsBeforeFailing := int(220) fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, filename) t.Log("recursion count - ", count) inputData := buildInputFromuint64(count) @@ -157,7 +160,7 @@ func TestFEVMRecursiveDelegatecallCount(t *testing.T) { ctx, cancel, client := kit.SetupFEVMTest(t) defer cancel() - highestSuccessCount := uint64(237) + highestSuccessCount := uint64(225) filename := "contracts/RecursiveDelegeatecall.hex" recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(1)) @@ -601,10 +604,10 @@ func TestFEVMRecursiveActorCall(t *testing.T) { t.Run("n=200,r=32", testN(200, 32, exitcode.Ok)) t.Run("n=251,r=32", testN(251, 32, exitcode.Ok)) - t.Run("n=0,r=254", testN(0, 254, exitcode.Ok)) + t.Run("n=0,r=252", testN(0, 252, exitcode.Ok)) t.Run("n=251,r=166", testN(251, 166, exitcode.Ok)) - t.Run("n=0,r=256-fails", testN(0, 256, exitcode.ExitCode(33))) // 33 means transaction reverted + t.Run("n=0,r=253-fails", testN(0, 253, exitcode.ExitCode(33))) // 33 means transaction reverted t.Run("n=251,r=167-fails", testN(251, 167, exitcode.ExitCode(33))) } @@ -704,3 +707,139 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) { t.Run("n=50", testN(50)) t.Run("n=100", testN(100)) } + +// TestFEVM deploys a contract while sending value to it +func TestFEVMDeployWithValue(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //testValue is the amount sent when the contract is created + //at the end we check that the new contract has a balance of testValue + testValue := big.NewInt(20) + + // deploy DeployValueTest which creates NewContract + // testValue is sent to DeployValueTest and that amount is + // also sent to NewContract + filenameActor := "contracts/DeployValueTest.hex" + fromAddr, idAddr := client.EVM().DeployContractFromFilenameWithValue(ctx, filenameActor, testValue) + + //call getNewContractBalance to find the value of NewContract + ret, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "getNewContractBalance()", []byte{}) + require.NoError(t, err) + + contractBalance, err := decodeOutputToUint64(ret) + require.NoError(t, err) + + //require balance of NewContract is testValue + require.Equal(t, testValue.Uint64(), contractBalance) +} + +func TestFEVMDestroyCreate2(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //deploy create2 factory contract + filename := "contracts/Create2Factory.hex" + fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, filename) + + //construct salt for create2 + salt := make([]byte, 32) + _, err := rand.Read(salt) + require.NoError(t, err) + + //deploy contract using create2 factory + selfDestructAddress, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "deploy(bytes32)", salt) + require.NoError(t, err) + + //convert to filecoin actor address so we can call InvokeContractByFuncName + ea, err := ethtypes.CastEthAddress(selfDestructAddress[12:]) + require.NoError(t, err) + selfDestructAddressActor, err := ea.ToFilecoinAddress() + require.NoError(t, err) + + //read sender property from contract + ret, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + + //assert contract has correct data + ethFromAddr := inputDataFromFrom(ctx, t, client, fromAddr) + require.Equal(t, ethFromAddr, ret) + + //run test() which 1.calls sefldestruct 2. verifies sender() is the correct value 3. attempts and fails to deploy via create2 + testSenderAddress, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "test(address)", selfDestructAddress) + require.NoError(t, err) + require.Equal(t, testSenderAddress, ethFromAddr) + + //read sender() but get response of 0x0 because of self destruct + senderAfterDestroy, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + require.Equal(t, []byte{}, senderAfterDestroy) + + // deploy new contract at same address usign same salt + newAddressSelfDestruct, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "deploy(bytes32)", salt) + require.NoError(t, err) + require.Equal(t, newAddressSelfDestruct, selfDestructAddress) + + //verify sender() property is correct + senderSecondCall, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + + //assert contract has correct data + require.Equal(t, ethFromAddr, senderSecondCall) + +} + +func TestFEVMBareTransferTriggersSmartContractLogic(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + // This contract emits an event on receiving value. + filename := "contracts/ValueSender.hex" + _, contractAddr := client.EVM().DeployContractFromFilename(ctx, filename) + + accctKey, accntEth, accntFil := client.EVM().NewAccount() + kit.SendFunds(ctx, t, client, accntFil, types.FromFil(10)) + + contractEth, err := ethtypes.EthAddressFromFilecoinAddress(contractAddr) + require.NoError(t, err) + + gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + From: &accntEth, + To: &contractEth, + Value: ethtypes.EthBigInt(big.NewInt(100)), + }) + require.NoError(t, err) + + maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) + require.NoError(t, err) + + tx := ethtypes.EthTxArgs{ + ChainID: build.Eip155ChainId, + Value: big.NewInt(100), + Nonce: 0, + To: &contractEth, + MaxFeePerGas: types.NanoFil, + MaxPriorityFeePerGas: big.Int(maxPriorityFeePerGas), + GasLimit: int(gaslimit), + V: big.Zero(), + R: big.Zero(), + S: big.Zero(), + } + + client.EVM().SignTransaction(&tx, accctKey.PrivateKey) + + hash := client.EVM().SubmitTransaction(ctx, &tx) + + var receipt *api.EthTxReceipt + for i := 0; i < 1000; i++ { + receipt, err = client.EthGetTransactionReceipt(ctx, hash) + require.NoError(t, err) + if receipt != nil { + break + } + time.Sleep(500 * time.Millisecond) + } + + // The receive() function emits one log, that's how we know we hit it. + require.Len(t, receipt.Logs, 1) +} diff --git a/itests/gas_estimation_test.go b/itests/gas_estimation_test.go index 42cad8611..24013c885 100644 --- a/itests/gas_estimation_test.go +++ b/itests/gas_estimation_test.go @@ -2,16 +2,23 @@ package itests import ( "context" + "math" "testing" "time" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/actors/builtin/account" "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/vm" "github.com/filecoin-project/lotus/itests/kit" ) @@ -37,8 +44,9 @@ func TestEstimateGasNoFunds(t *testing.T) { sm, err := client.MpoolPushMessage(ctx, msg, nil) require.NoError(t, err) - _, err = client.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true) + ret, err := client.StateWaitMsg(ctx, sm.Cid(), 3, api.LookbackNoLimit, true) require.NoError(t, err) + require.True(t, ret.Receipt.ExitCode.IsSuccess()) // Make sure we can estimate gas even if we have no funds. msg2 := &types.Message{ @@ -52,3 +60,110 @@ func TestEstimateGasNoFunds(t *testing.T) { require.NoError(t, err) require.NotZero(t, limit) } + +// Make sure that we correctly calculate the inclusion cost. Especially, make sure the FVM and Lotus +// agree and that: +// 1. The FVM will never charge _less_ than the inclusion cost. +// 2. The FVM will never fine a storage provider for including a message that costs exactly the +// inclusion cost. +func TestEstimateInclusion(t *testing.T) { + ctx := context.Background() + + kit.QuietMiningLogs() + + // We need this to be "correct" in this test so that lotus can get the correct gas value + // (which, unfortunately, looks at the height and not the current network version). + oldPrices := vm.Prices + vm.Prices = map[abi.ChainEpoch]vm.Pricelist{ + 0: oldPrices[build.UpgradeHyggeHeight], + } + t.Cleanup(func() { vm.Prices = oldPrices }) + + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs()) + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + // First, try sending a message that should have no fees beyond the inclusion cost. I.e., it + // does absolutely nothing: + msg := &types.Message{ + From: client.DefaultKey.Address, + To: client.DefaultKey.Address, + Value: big.Zero(), + GasLimit: 0, + GasFeeCap: abi.NewTokenAmount(10000), + GasPremium: big.Zero(), + } + + burntBefore, err := client.WalletBalance(ctx, builtin.BurntFundsActorAddr) + require.NoError(t, err) + balanceBefore, err := client.WalletBalance(ctx, client.DefaultKey.Address) + require.NoError(t, err) + + // Sign the message and compute the correct inclusion cost. + var smsg *types.SignedMessage + for i := 0; ; i++ { + var err error + smsg, err = client.WalletSignMessage(ctx, client.DefaultKey.Address, msg) + require.NoError(t, err) + estimatedGas := vm.PricelistByEpoch(math.MaxInt).OnChainMessage(smsg.ChainLength()).Total() + if estimatedGas == msg.GasLimit { + break + } + // Try 10 times to get the right gas value. + require.Less(t, i, 10, "unable to estimate gas: %s != %s", estimatedGas, msg.GasLimit) + msg.GasLimit = estimatedGas + } + + cid, err := client.MpoolPush(ctx, smsg) + require.NoError(t, err) + ret, err := client.StateWaitMsg(ctx, cid, 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.True(t, ret.Receipt.ExitCode.IsSuccess()) + require.Equal(t, msg.GasLimit, ret.Receipt.GasUsed) + + // Then try sending a message of the same size that tries to create an actor. This should + // get successfully included, but fail with out of gas: + + // Mutate the last byte to get a new address of the same length. + toBytes := msg.To.Bytes() + toBytes[len(toBytes)-1] += 1 //nolint:golint + newAddr, err := address.NewFromBytes(toBytes) + require.NoError(t, err) + + msg.Nonce = 1 + msg.To = newAddr + smsg, err = client.WalletSignMessage(ctx, client.DefaultKey.Address, msg) + require.NoError(t, err) + + cid, err = client.MpoolPush(ctx, smsg) + require.NoError(t, err) + ret, err = client.StateWaitMsg(ctx, cid, 3, api.LookbackNoLimit, true) + require.NoError(t, err) + require.Equal(t, ret.Receipt.ExitCode, exitcode.SysErrOutOfGas) + require.Equal(t, msg.GasLimit, ret.Receipt.GasUsed) + + // Now make sure that the client is the only contributor to the burnt funds actor (the + // miners should not have been fined for either message). + + burntAfter, err := client.WalletBalance(ctx, builtin.BurntFundsActorAddr) + require.NoError(t, err) + balanceAfter, err := client.WalletBalance(ctx, client.DefaultKey.Address) + require.NoError(t, err) + + burnt := big.Sub(burntAfter, burntBefore) + spent := big.Sub(balanceBefore, balanceAfter) + + require.Equal(t, burnt, spent) + + // Finally, try to submit a message with too little gas. This should fail. + + msg.Nonce = 2 + msg.To = msg.From + msg.GasLimit -= 1 //nolint:golint + + smsg, err = client.WalletSignMessage(ctx, client.DefaultKey.Address, msg) + require.NoError(t, err) + + _, err = client.MpoolPush(ctx, smsg) + require.ErrorContains(t, err, "will not be included in a block") + require.ErrorContains(t, err, "cannot be less than the cost of storing a message") +} diff --git a/itests/kit/evm.go b/itests/kit/evm.go index eac8f0234..3cbfcd5f2 100644 --- a/itests/kit/evm.go +++ b/itests/kit/evm.go @@ -43,19 +43,18 @@ func (f *TestFullNode) EVM() *EVM { return &EVM{f} } -func (e *EVM) DeployContract(ctx context.Context, sender address.Address, bytecode []byte) eam.CreateReturn { - var err error +func (e *EVM) DeployContractWithValue(ctx context.Context, sender address.Address, bytecode []byte, value big.Int) eam.CreateReturn { require := require.New(e.t) method := builtintypes.MethodsEAM.CreateExternal initcode := abi.CborBytes(bytecode) - params, err := actors.SerializeParams(&initcode) - require.NoError(err) + params, errActors := actors.SerializeParams(&initcode) + require.NoError(errActors) msg := &types.Message{ To: builtintypes.EthereumAddressManagerActorAddr, From: sender, - Value: big.Zero(), + Value: value, Method: method, Params: params, } @@ -65,7 +64,7 @@ func (e *EVM) DeployContract(ctx context.Context, sender address.Address, byteco require.NoError(err) e.t.Log("waiting for message to execute") - wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 0, 0, false) + wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 3, 0, false) require.NoError(err) require.True(wait.Receipt.ExitCode.IsSuccess(), "contract installation failed") @@ -77,8 +76,11 @@ func (e *EVM) DeployContract(ctx context.Context, sender address.Address, byteco return result } +func (e *EVM) DeployContract(ctx context.Context, sender address.Address, bytecode []byte) eam.CreateReturn { + return e.DeployContractWithValue(ctx, sender, bytecode, big.Zero()) +} -func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string) (address.Address, address.Address) { +func (e *EVM) DeployContractFromFilenameWithValue(ctx context.Context, binFilename string, value big.Int) (address.Address, address.Address) { contractHex, err := os.ReadFile(binFilename) require.NoError(e.t, err) @@ -91,12 +93,15 @@ func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string fromAddr, err := e.WalletDefaultAddress(ctx) require.NoError(e.t, err) - result := e.DeployContract(ctx, fromAddr, contract) + result := e.DeployContractWithValue(ctx, fromAddr, contract, value) idAddr, err := address.NewIDAddress(result.ActorID) require.NoError(e.t, err) return fromAddr, idAddr } +func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string) (address.Address, address.Address) { + return e.DeployContractFromFilenameWithValue(ctx, binFilename, big.Zero()) +} func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target address.Address, selector []byte, inputData []byte) (*api.MsgLookup, error) { params := append(selector, inputData...) @@ -123,7 +128,7 @@ func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target } e.t.Log("waiting for message to execute") - wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 0, 0, false) + wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 3, 0, false) if err != nil { return nil, err } @@ -349,7 +354,7 @@ func SetupFEVMTest(t *testing.T) (context.Context, context.CancelFunc, *TestFull return ctx, cancel, client } -func (e *EVM) TransferValueOrFail(ctx context.Context, fromAddr address.Address, toAddr address.Address, sendAmount big.Int) { +func (e *EVM) TransferValueOrFail(ctx context.Context, fromAddr address.Address, toAddr address.Address, sendAmount big.Int) *api.MsgLookup { sendMsg := &types.Message{ From: fromAddr, To: toAddr, @@ -360,6 +365,7 @@ func (e *EVM) TransferValueOrFail(ctx context.Context, fromAddr address.Address, mLookup, err := e.StateWaitMsg(ctx, signedMsg.Cid(), 3, api.LookbackNoLimit, true) require.NoError(e.t, err) require.Equal(e.t, exitcode.Ok, mLookup.Receipt.ExitCode) + return mLookup } func NewEthFilterBuilder() *EthFilterBuilder { diff --git a/itests/kit/solidity.go b/itests/kit/solidity.go index ea9d452f4..6999bd91b 100644 --- a/itests/kit/solidity.go +++ b/itests/kit/solidity.go @@ -2,12 +2,16 @@ package kit import ( "golang.org/x/crypto/sha3" + + "github.com/filecoin-project/lotus/chain/types/ethtypes" ) -func EthTopicHash(sig string) []byte { +func EthTopicHash(sig string) ethtypes.EthHash { hasher := sha3.NewLegacyKeccak256() hasher.Write([]byte(sig)) - return hasher.Sum(nil) + var hash ethtypes.EthHash + copy(hash[:], hasher.Sum(nil)) + return hash } func EthFunctionHash(sig string) []byte { @@ -18,9 +22,9 @@ func EthFunctionHash(sig string) []byte { // SolidityContractDef holds information about one of the test contracts type SolidityContractDef struct { - Filename string // filename of the hex of the contract, e.g. contracts/EventMatrix.hex - Fn map[string][]byte // mapping of function names to 32-bit selector - Ev map[string][]byte // mapping of event names to 256-bit signature hashes + Filename string // filename of the hex of the contract, e.g. contracts/EventMatrix.hex + Fn map[string][]byte // mapping of function names to 32-bit selector + Ev map[string]ethtypes.EthHash // mapping of event names to 256-bit signature hashes } var EventMatrixContract = SolidityContractDef{ @@ -38,7 +42,7 @@ var EventMatrixContract = SolidityContractDef{ "logEventTwoIndexedWithData": EthFunctionHash("logEventTwoIndexedWithData(uint256,uint256,uint256)"), "logEventThreeIndexedWithData": EthFunctionHash("logEventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), }, - Ev: map[string][]byte{ + Ev: map[string]ethtypes.EthHash{ "EventZeroData": EthTopicHash("EventZeroData()"), "EventOneData": EthTopicHash("EventOneData(uint256)"), "EventTwoData": EthTopicHash("EventTwoData(uint256,uint256)"), @@ -60,5 +64,5 @@ var EventsContract = SolidityContractDef{ "log_zero_nodata": {0x00, 0x00, 0x00, 0x01}, "log_four_data": {0x00, 0x00, 0x00, 0x02}, }, - Ev: map[string][]byte{}, + Ev: map[string]ethtypes.EthHash{}, } diff --git a/itests/wdpost_dispute_test.go b/itests/wdpost_dispute_test.go index eedb3e8f6..c4512874a 100644 --- a/itests/wdpost_dispute_test.go +++ b/itests/wdpost_dispute_test.go @@ -113,7 +113,7 @@ func TestWindowPostDispute(t *testing.T) { //stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001 di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) require.NoError(t, err) - if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.PeriodStart > 1 { + if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.Open > 1 { break } build.Clock.Sleep(blocktime) @@ -217,7 +217,8 @@ func TestWindowPostDispute(t *testing.T) { //stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001 di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) require.NoError(t, err) - if di.Index == evilSectorLoc.Deadline { + + if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.Open > 1 { break } build.Clock.Sleep(blocktime) diff --git a/node/impl/full/dummy.go b/node/impl/full/dummy.go index c1c6ea975..9abe00321 100644 --- a/node/impl/full/dummy.go +++ b/node/impl/full/dummy.go @@ -12,7 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/types/ethtypes" ) -var ErrModuleDisabled = errors.New("module disabled, enable with Fevm.EnableEthRPC / LOTUS_FEVM_ENABLEETHPRC") +var ErrModuleDisabled = errors.New("module disabled, enable with Fevm.EnableEthRPC / LOTUS_FEVM_ENABLEETHRPC") type EthModuleDummy struct{} @@ -80,7 +80,7 @@ func (e *EthModuleDummy) EthGetBalance(ctx context.Context, address ethtypes.Eth return ethtypes.EthBigIntZero, ErrModuleDisabled } -func (e *EthModuleDummy) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) { +func (e *EthModuleDummy) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { return ethtypes.EthFeeHistory{}, ErrModuleDisabled } diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 6d144b9ae..9576dee40 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -57,7 +57,7 @@ type EthModuleAPI interface { 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) - EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) + EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) NetVersion(ctx context.Context) (string, error) NetListening(ctx context.Context) (bool, error) @@ -426,22 +426,6 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, return nil, xerrors.Errorf("cannot get Filecoin address: %w", err) } - // use the system actor as the caller - from, err := address.NewIDAddress(0) - if err != nil { - return nil, fmt.Errorf("failed to construct system sender address: %w", err) - } - msg := &types.Message{ - From: from, - To: to, - Value: big.Zero(), - Method: builtintypes.MethodsEVM.GetBytecode, - Params: nil, - GasLimit: build.BlockGasLimit, - GasFeeCap: big.Zero(), - GasPremium: big.Zero(), - } - ts, err := a.parseBlkParam(ctx, blkParam) if err != nil { return nil, xerrors.Errorf("cannot parse block param: %s", blkParam) @@ -452,6 +436,31 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, return nil, xerrors.Errorf("block param must not specify genesis block") } + actor, err := a.StateManager.LoadActor(ctx, to, ts) + if err != nil { + if xerrors.Is(err, types.ErrActorNotFound) { + return nil, nil + } + return nil, xerrors.Errorf("failed to lookup contract %s: %w", ethAddr, err) + } + + // Not a contract. We could try to distinguish between accounts and "native" contracts here, + // but it's not worth it. + if !builtinactors.IsEvmActor(actor.Code) { + return nil, nil + } + + msg := &types.Message{ + From: builtinactors.SystemActorAddr, + To: to, + Value: big.Zero(), + Method: builtintypes.MethodsEVM.GetBytecode, + Params: nil, + GasLimit: build.BlockGasLimit, + GasFeeCap: big.Zero(), + GasPremium: big.Zero(), + } + // Try calling until we find a height with no migration. var res *api.InvocResult for { @@ -466,9 +475,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, } if err != nil { - // if the call resulted in error, this is not an EVM smart contract; - // return no bytecode. - return nil, nil + return nil, xerrors.Errorf("failed to call GetBytecode: %w", err) } if res.MsgRct == nil { @@ -476,15 +483,20 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, } if res.MsgRct.ExitCode.IsError() { - return nil, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error) + return nil, xerrors.Errorf("GetBytecode failed: %s", res.Error) } - var bytecodeCid cbg.CborCid - if err := bytecodeCid.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return)); err != nil { + var getBytecodeReturn evm.GetBytecodeReturn + if err := getBytecodeReturn.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return)); err != nil { return nil, fmt.Errorf("failed to decode EVM bytecode CID: %w", err) } - blk, err := a.Chain.StateBlockstore().Get(ctx, cid.Cid(bytecodeCid)) + // The contract has selfdestructed, so the code is "empty". + if getBytecodeReturn.Cid == nil { + return nil, nil + } + + blk, err := a.Chain.StateBlockstore().Get(ctx, *getBytecodeReturn.Cid) if err != nil { return nil, fmt.Errorf("failed to get EVM bytecode: %w", err) } @@ -581,35 +593,30 @@ func (a *EthModule) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) return ethtypes.EthUint64(build.Eip155ChainId), nil } -func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlkNum string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) { - if blkCount > 1024 { +func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthFeeHistory, error) { + params, err := jsonrpc.DecodeParams[ethtypes.EthFeeHistoryParams](p) + if err != nil { + return ethtypes.EthFeeHistory{}, xerrors.Errorf("decoding params: %w", err) + } + if params.BlkCount > 1024 { return ethtypes.EthFeeHistory{}, fmt.Errorf("block count should be smaller than 1024") } - newestBlkHeight := uint64(a.Chain.GetHeaviestTipSet().Height()) - - // TODO https://github.com/filecoin-project/ref-fvm/issues/1016 - var blkNum ethtypes.EthUint64 - err := blkNum.UnmarshalJSON([]byte(`"` + newestBlkNum + `"`)) - if err == nil && uint64(blkNum) < newestBlkHeight { - newestBlkHeight = uint64(blkNum) - } - - // Deal with the case that the chain is shorter than the number of - // requested blocks. - oldestBlkHeight := uint64(1) - if uint64(blkCount) <= newestBlkHeight { - oldestBlkHeight = newestBlkHeight - uint64(blkCount) + 1 - } - - ts, err := a.Chain.GetTipsetByHeight(ctx, abi.ChainEpoch(newestBlkHeight), nil, false) + ts, err := a.parseBlkParam(ctx, params.NewestBlkNum) if err != nil { - return ethtypes.EthFeeHistory{}, fmt.Errorf("cannot load find block height: %v", newestBlkHeight) + return ethtypes.EthFeeHistory{}, fmt.Errorf("bad block parameter %s: %s", params.NewestBlkNum, err) } - // FIXME: baseFeePerGas should include the next block after the newest of the returned range, because this - // can be inferred from the newest block. we use the newest block's baseFeePerGas for now but need to fix it - // In other words, due to deferred execution, we might not be returning the most useful value here for the client. + // Deal with the case that the chain is shorter than the number of requested blocks. + oldestBlkHeight := uint64(1) + if abi.ChainEpoch(params.BlkCount) <= ts.Height() { + oldestBlkHeight = uint64(ts.Height()) - uint64(params.BlkCount) + 1 + } + + // NOTE: baseFeePerGas should include the next block after the newest of the returned range, + // because the next base fee can be inferred from the messages in the newest block. + // However, this is NOT the case in Filecoin due to deferred execution, so the best + // we can do is duplicate the last value. baseFeeArray := []ethtypes.EthBigInt{ethtypes.EthBigInt(ts.Blocks()[0].ParentBaseFee)} gasUsedRatioArray := []float64{} @@ -633,7 +640,6 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint } // Reverse the arrays; we collected them newest to oldest; the client expects oldest to newest. - for i, j := 0, len(baseFeeArray)-1; i < j; i, j = i+1, j-1 { baseFeeArray[i], baseFeeArray[j] = baseFeeArray[j], baseFeeArray[i] } @@ -641,11 +647,21 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint gasUsedRatioArray[i], gasUsedRatioArray[j] = gasUsedRatioArray[j], gasUsedRatioArray[i] } - return ethtypes.EthFeeHistory{ + ret := ethtypes.EthFeeHistory{ OldestBlock: ethtypes.EthUint64(oldestBlkHeight), BaseFeePerGas: baseFeeArray, GasUsedRatio: gasUsedRatioArray, - }, nil + } + if params.RewardPercentiles != nil { + // TODO: Populate reward percentiles + // https://github.com/filecoin-project/lotus/issues/10236 + // We need to calculate the requested percentiles of effective gas premium + // based on the newest block (I presume it's the newest, we need to dig in + // as it's underspecified). Effective means we're clamped at the gas_fee_cap - base_fee. + reward := make([][]ethtypes.EthBigInt, 0) + ret.Reward = &reward + } + return ret, nil } func (a *EthModule) NetVersion(ctx context.Context) (string, error) { @@ -761,10 +777,9 @@ func (a *EthModule) ethCallToFilecoinMessage(ctx context.Context, tx ethtypes.Et return nil, fmt.Errorf("failed to encode tx input into a cbor byte-string") } params = buf.Bytes() - method = builtintypes.MethodsEVM.InvokeContract - } else { - method = builtintypes.MethodSend } + + method = builtintypes.MethodsEVM.InvokeContract } return &types.Message{ @@ -1358,6 +1373,67 @@ type filterTipSetCollector interface { TakeCollectedTipSets(context.Context) []types.TipSetKey } +func ethLogFromEvent(entries []types.EventEntry) (data []byte, topics []ethtypes.EthHash, ok bool) { + var ( + topicsFound [4]bool + topicsFoundCount int + dataFound bool + ) + for _, entry := range entries { + // Drop events with non-raw topics to avoid mistakes. + if entry.Codec != cid.Raw { + log.Warnw("did not expect an event entry with a non-raw codec", "codec", entry.Codec, "key", entry.Key) + return nil, nil, false + } + // Check if the key is t1..t4 + if len(entry.Key) == 2 && "t1" <= entry.Key && entry.Key <= "t4" { + // '1' - '1' == 0, etc. + idx := int(entry.Key[1] - '1') + + // Drop events with mis-sized topics. + if len(entry.Value) != 32 { + log.Warnw("got an EVM event topic with an invalid size", "key", entry.Key, "size", len(entry.Value)) + return nil, nil, false + } + + // Drop events with duplicate topics. + if topicsFound[idx] { + log.Warnw("got a duplicate EVM event topic", "key", entry.Key) + return nil, nil, false + } + topicsFound[idx] = true + topicsFoundCount++ + + // Extend the topics array + for len(topics) <= idx { + topics = append(topics, ethtypes.EthHash{}) + } + copy(topics[idx][:], entry.Value) + } else if entry.Key == "d" { + // Drop events with duplicate data fields. + if dataFound { + log.Warnw("got duplicate EVM event data") + return nil, nil, false + } + + dataFound = true + data = entry.Value + } else { + // Skip entries we don't understand (makes it easier to extend things). + // But we warn for now because we don't expect them. + log.Warnw("unexpected event entry", "key", entry.Key) + } + + } + + // Drop events with skipped topics. + if len(topics) != topicsFoundCount { + log.Warnw("EVM event topic length mismatch", "expected", len(topics), "actual", topicsFoundCount) + return nil, nil, false + } + return data, topics, true +} + func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*ethtypes.EthFilterResult, error) { res := ðtypes.EthFilterResult{} for _, ev := range evs { @@ -1367,19 +1443,14 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht TransactionIndex: ethtypes.EthUint64(ev.MsgIdx), BlockNumber: ethtypes.EthUint64(ev.Height), } + var ( + err error + ok bool + ) - var err error - - for _, entry := range ev.Entries { - value, err := cborDecodeTopicValue(entry.Value) - if err != nil { - return nil, err - } - if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 { - log.Topics = append(log.Topics, value) - } else { - log.Data = value - } + log.Data, log.Topics, ok = ethLogFromEvent(ev.Entries) + if !ok { + continue } log.Address, err = ethtypes.EthAddressFromFilecoinAddress(ev.EmitterAddr) @@ -1517,45 +1588,50 @@ func (e *ethSubscription) addFilter(ctx context.Context, f filter.Filter) { e.filters = append(e.filters, f) } +func (e *ethSubscription) send(ctx context.Context, v interface{}) { + resp := ethtypes.EthSubscriptionResponse{ + SubscriptionID: e.id, + Result: v, + } + + outParam, err := json.Marshal(resp) + if err != nil { + log.Warnw("marshaling subscription response", "sub", e.id, "error", err) + return + } + + if err := e.out(ctx, outParam); err != nil { + log.Warnw("sending subscription response", "sub", e.id, "error", err) + return + } +} + func (e *ethSubscription) start(ctx context.Context) { for { select { case <-ctx.Done(): return case v := <-e.in: - resp := ethtypes.EthSubscriptionResponse{ - SubscriptionID: e.id, - } - - var err error switch vt := v.(type) { case *filter.CollectedEvent: - resp.Result, err = ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI) + evs, err := ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI) + if err != nil { + continue + } + + for _, r := range evs.Results { + e.send(ctx, r) + } case *types.TipSet: - eb, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.StateAPI) + ev, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.StateAPI) if err != nil { break } - resp.Result = eb + e.send(ctx, ev) default: log.Warnf("unexpected subscription value type: %T", vt) } - - if err != nil { - continue - } - - outParam, err := json.Marshal(resp) - if err != nil { - log.Warnw("marshaling subscription response", "sub", e.id, "error", err) - continue - } - - if err := e.out(ctx, outParam); err != nil { - log.Warnw("sending subscription response", "sub", e.id, "error", err) - continue - } } } } @@ -1757,6 +1833,7 @@ func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, sa StateAPI Gas: ethtypes.EthUint64(msg.GasLimit), MaxFeePerGas: ethtypes.EthBigInt(msg.GasFeeCap), MaxPriorityFeePerGas: ethtypes.EthBigInt(msg.GasPremium), + AccessList: []ethtypes.EthHash{}, } } @@ -1890,11 +1967,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook } if len(events) > 0 { - // TODO return a dummy non-zero bloom to signal that there are logs - // need to figure out how worth it is to populate with a real bloom - // should be feasible here since we are iterating over the logs anyway - receipt.LogsBloom[255] = 0x01 - receipt.Logs = make([]ethtypes.EthLog, 0, len(events)) for i, evt := range events { l := ethtypes.EthLog{ @@ -1906,17 +1978,16 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook BlockNumber: blockNumber, } - for _, entry := range evt.Entries { - value, err := cborDecodeTopicValue(entry.Value) - if err != nil { - return api.EthTxReceipt{}, xerrors.Errorf("failed to decode event log value: %w", err) - } - if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 { - l.Topics = append(l.Topics, value) - } else { - l.Data = value - } + data, topics, ok := ethLogFromEvent(evt.Entries) + if !ok { + // not an eth event. + continue } + for _, topic := range topics { + ethtypes.EthBloomSet(receipt.LogsBloom, topic[:]) + } + l.Data = data + l.Topics = topics addr, err := address.NewIDAddress(uint64(evt.Emitter)) if err != nil { @@ -1928,6 +1999,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err) } + ethtypes.EthBloomSet(receipt.LogsBloom, l.Address[:]) receipt.Logs = append(receipt.Logs, l) } } @@ -1971,6 +2043,52 @@ func (m *EthTxHashManager) Revert(ctx context.Context, from, to *types.TipSet) e return nil } +func (m *EthTxHashManager) PopulateExistingMappings(ctx context.Context, minHeight abi.ChainEpoch) error { + if minHeight < build.UpgradeHyggeHeight { + minHeight = build.UpgradeHyggeHeight + } + + ts := m.StateAPI.Chain.GetHeaviestTipSet() + for ts.Height() > minHeight { + for _, block := range ts.Blocks() { + msgs, err := m.StateAPI.Chain.SecpkMessagesForBlock(ctx, block) + if err != nil { + // If we can't find the messages, we've either imported from snapshot or pruned the store + log.Debug("exiting message mapping population at epoch ", ts.Height()) + return nil + } + + for _, msg := range msgs { + m.ProcessSignedMessage(ctx, msg) + } + } + + var err error + ts, err = m.StateAPI.Chain.GetTipSetFromKey(ctx, ts.Parents()) + if err != nil { + return err + } + } + + return nil +} + +func (m *EthTxHashManager) ProcessSignedMessage(ctx context.Context, msg *types.SignedMessage) { + if msg.Signature.Type != crypto.SigTypeDelegated { + return + } + + ethTx, err := newEthTxFromSignedMessage(ctx, msg, m.StateAPI) + if err != nil { + log.Errorf("error converting filecoin message to eth tx: %s", err) + } + + err = m.TransactionHashLookup.UpsertHash(ethTx.Hash, msg.Cid()) + if err != nil { + log.Errorf("error inserting tx mapping to db: %s", err) + } +} + func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager *EthTxHashManager) { for { select { @@ -1980,19 +2098,8 @@ func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager if u.Type != api.MpoolAdd { continue } - if u.Message.Signature.Type != crypto.SigTypeDelegated { - continue - } - ethTx, err := newEthTxFromSignedMessage(ctx, u.Message, manager.StateAPI) - if err != nil { - log.Errorf("error converting filecoin message to eth tx: %s", err) - } - - err = manager.TransactionHashLookup.UpsertHash(ethTx.Hash, u.Message.Cid()) - if err != nil { - log.Errorf("error inserting tx mapping to db: %s", err) - } + manager.ProcessSignedMessage(ctx, u.Message) } } } @@ -2013,45 +2120,6 @@ func EthTxHashGC(ctx context.Context, retentionDays int, manager *EthTxHashManag } } -func leftpad32(orig []byte) []byte { - needed := 32 - len(orig) - if needed <= 0 { - return orig - } - ret := make([]byte, 32) - copy(ret[needed:], orig) - return ret -} - -func trimLeadingZeros(b []byte) []byte { - for i := range b { - if b[i] != 0 { - return b[i:] - } - } - return []byte{} -} - -func cborEncodeTopicValue(orig []byte) ([]byte, error) { - var buf bytes.Buffer - err := cbg.WriteByteArray(&buf, trimLeadingZeros(orig)) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func cborDecodeTopicValue(orig []byte) ([]byte, error) { - if len(orig) == 0 { - return orig, nil - } - decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig))) - if err != nil { - return nil, err - } - return leftpad32(decoded), nil -} - func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) { keys := map[string][][]byte{} for idx, vals := range topics { @@ -2061,11 +2129,8 @@ func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) { // Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4 key := fmt.Sprintf("t%d", idx+1) for _, v := range vals { - encodedVal, err := cborEncodeTopicValue(v[:]) - if err != nil { - return nil, xerrors.Errorf("failed to encode topic value") - } - keys[key] = append(keys[key], encodedVal) + v := v // copy the ethhash to avoid repeatedly referencing the same one. + keys[key] = append(keys[key], v[:]) } } return keys, nil diff --git a/node/impl/full/eth_test.go b/node/impl/full/eth_test.go new file mode 100644 index 000000000..027becf34 --- /dev/null +++ b/node/impl/full/eth_test.go @@ -0,0 +1,102 @@ +package full + +import ( + "testing" + + "github.com/ipfs/go-cid" + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" +) + +func TestEthLogFromEvent(t *testing.T) { + // basic empty + data, topics, ok := ethLogFromEvent(nil) + require.True(t, ok) + require.Nil(t, data) + require.Nil(t, topics) + + // basic topic + data, topics, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "t1", + Codec: cid.Raw, + Value: make([]byte, 32), + }}) + require.True(t, ok) + require.Nil(t, data) + require.Len(t, topics, 1) + require.Equal(t, topics[0], ethtypes.EthHash{}) + + // basic topic with data + data, topics, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "t1", + Codec: cid.Raw, + Value: make([]byte, 32), + }, { + Flags: 0, + Key: "d", + Codec: cid.Raw, + Value: []byte{0x0}, + }}) + require.True(t, ok) + require.Equal(t, data, []byte{0x0}) + require.Len(t, topics, 1) + require.Equal(t, topics[0], ethtypes.EthHash{}) + + // skip topic + _, _, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "t2", + Codec: cid.Raw, + Value: make([]byte, 32), + }}) + require.False(t, ok) + + // duplicate topic + _, _, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "t1", + Codec: cid.Raw, + Value: make([]byte, 32), + }, { + Flags: 0, + Key: "t1", + Codec: cid.Raw, + Value: make([]byte, 32), + }}) + require.False(t, ok) + + // duplicate data + _, _, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "d", + Codec: cid.Raw, + Value: make([]byte, 32), + }, { + Flags: 0, + Key: "d", + Codec: cid.Raw, + Value: make([]byte, 32), + }}) + require.False(t, ok) + + // unknown key is fine + data, topics, ok = ethLogFromEvent([]types.EventEntry{{ + Flags: 0, + Key: "t5", + Codec: cid.Raw, + Value: make([]byte, 32), + }, { + Flags: 0, + Key: "t1", + Codec: cid.Raw, + Value: make([]byte, 32), + }}) + require.True(t, ok) + require.Nil(t, data) + require.Len(t, topics, 1) + require.Equal(t, topics[0], ethtypes.EthHash{}) +} diff --git a/node/impl/full/wallet.go b/node/impl/full/wallet.go index 0927e5aca..fdf00e086 100644 --- a/node/impl/full/wallet.go +++ b/node/impl/full/wallet.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/wallet" - "github.com/filecoin-project/lotus/chain/wallet/key" "github.com/filecoin-project/lotus/lib/sigs" ) @@ -53,11 +52,7 @@ func (a *WalletAPI) WalletSignMessage(ctx context.Context, k address.Address, ms return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr) } - keyInfo, err := a.Wallet.WalletExport(ctx, k) - if err != nil { - return nil, err - } - sb, err := messagesigner.SigningBytes(msg, key.ActSigType(keyInfo.Type)) + sb, err := messagesigner.SigningBytes(msg, keyAddr.Protocol()) if err != nil { return nil, err } diff --git a/node/modules/ethmodule.go b/node/modules/ethmodule.go index 9889233f4..eba6c54d1 100644 --- a/node/modules/ethmodule.go +++ b/node/modules/ethmodule.go @@ -2,6 +2,7 @@ package modules import ( "context" + "os" "path/filepath" "go.uber.org/fx" @@ -24,7 +25,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep return nil, err } - transactionHashLookup, err := ethhashlookup.NewTransactionHashLookup(filepath.Join(sqlitePath, "txhash.db")) + dbPath := filepath.Join(sqlitePath, "txhash.db") + + // Check if the db exists, if not, we'll back-fill some entries + _, err = os.Stat(dbPath) + dbAlreadyExists := err == nil + + transactionHashLookup, err := ethhashlookup.NewTransactionHashLookup(dbPath) if err != nil { return nil, err } @@ -40,6 +47,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep TransactionHashLookup: transactionHashLookup, } + if !dbAlreadyExists { + err = ethTxHashManager.PopulateExistingMappings(mctx, 0) + if err != nil { + return nil, err + } + } + const ChainHeadConfidence = 1 ctx := helpers.LifecycleCtx(mctx, lc)