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

This commit is contained in:
Aayush 2023-02-10 18:39:51 -05:00
commit 63b03a48d0
79 changed files with 1418 additions and 752 deletions

View File

@ -1040,13 +1040,6 @@ workflows:
- build - build
suite: conformance suite: conformance
target: "./conformance" target: "./conformance"
- test-conformance:
name: test-conformance-bleeding-edge
requires:
- build
suite: conformance-bleeding-edge
target: "./conformance"
vectors-branch: specs-actors-v7
release: release:
jobs: jobs:

View File

@ -571,13 +571,6 @@ workflows:
- build - build
suite: conformance suite: conformance
target: "./conformance" target: "./conformance"
- test-conformance:
name: test-conformance-bleeding-edge
requires:
- build
suite: conformance-bleeding-edge
target: "./conformance"
vectors-branch: specs-actors-v7
release: release:
jobs: jobs:

View File

@ -298,7 +298,7 @@ actors-gen: actors-code-gen fiximports
.PHONY: actors-gen .PHONY: actors-gen
bundle-gen: bundle-gen:
$(GOCC) run ./gen/bundle $(GOCC) run ./gen/bundle $(RELEASE)
$(GOCC) fmt ./build/... $(GOCC) fmt ./build/...
.PHONY: bundle-gen .PHONY: bundle-gen
@ -354,7 +354,7 @@ docsgen-openrpc-gateway: docsgen-openrpc-bin
fiximports: fiximports:
./scripts/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" @echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO MAKE docsgen-cli"
.PHONY: gen .PHONY: gen

View File

@ -52,4 +52,4 @@ popd
echo "Generating metadata..." echo "Generating metadata..."
make -C ../../ bundle-gen make -C ../../ RELEASE="$RELEASE" bundle-gen

Binary file not shown.

Binary file not shown.

View File

@ -1,2 +1,2 @@
/dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWKeDMuJbouvypr1nL2qRruhNVXzv4QiLsZRh6gnvLkc7p /dns4/bootstrap-0.butterfly.fildev.network/tcp/1347/p2p/12D3KooWHkVVMJ1rfVLM5poNrgwTJiaDkpDLkPqQ9zVuNPQ7AJ6p
/dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWSsACNHLGoJbPqeitNY7tom19Nxq8x5ag36eTwmgcAeLo /dns4/bootstrap-1.butterfly.fildev.network/tcp/1347/p2p/12D3KooWRyzqeQd51HCvVK3nvegmnBsYYPLSZbxR3Q9XAoUrUZ18

View File

@ -99,6 +99,7 @@ type BuiltinActorsMetadata struct {
Version actorstypes.Version Version actorstypes.Version
ManifestCid cid.Cid ManifestCid cid.Cid
Actors map[string]cid.Cid Actors map[string]cid.Cid
BundleGitTag string
} }
// ReadEmbeddedBuiltinActorsMetadata reads the metadata from the embedded built-in actor bundles. // ReadEmbeddedBuiltinActorsMetadata reads the metadata from the embedded built-in actor bundles.

View File

@ -9,6 +9,7 @@ import (
var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMetadata{{ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMetadata{{
Network: "butterflynet", Network: "butterflynet",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"),
@ -31,50 +32,49 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "butterflynet", Network: "butterflynet",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"),
ManifestCid: MustParseCid("bafy2bzacec35by4erhcdgcsgzp7yb3j57utydlxxfc73m3k5pep67ehvvyv6i"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), "account": MustParseCid("bafk2bzaceajsdln7v4chxqoukiw7lxw6aexg5qdsaex2hgelz2sbu24iblhzg"),
"cron": MustParseCid("bafk2bzacecrszortqkc7har77ssgajglymv6ftrqvmdko5h2yqqh5k2qospl2"), "cron": MustParseCid("bafk2bzacecgrwmgnqhybn3l23uvwf2n2vrcfjrprfzgd44uxers2pgr5mhsue"),
"datacap": MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e"), "datacap": MustParseCid("bafk2bzacebyier2ceh27acbrq2ccv4efvzotl6qntnlrxdsrik6i4tembz6qw"),
"eam": MustParseCid("bafk2bzacecflry2dyjqj6fhpovkbcbei377zabectznuxsf6bxggsve7bsxga"), "init": MustParseCid("bafk2bzaceberhto43wnf4pklkd4c7d36kzslngyzyms4op7shxuswv3dtvfxu"),
"ethaccount": MustParseCid("bafk2bzacedl4pmkfxkzoqajs6im3ranmopozsmxjcxsnk3kwvd3vv7mfwwrf4"), "multisig": MustParseCid("bafk2bzaceaclpbrhoqdruvsuqqgknvy2k5dywzmjoehk4uarce3uvt3w2rewu"),
"evm": MustParseCid("bafk2bzacebgzvmvwv7rsnnhp3zhqbiqkumvyrc7pazfovpptgpgtqkalrli74"), "paymentchannel": MustParseCid("bafk2bzacedzp56g5cg73oilloak3kf7u667rdkd5pgnhe2cljmr3o7ykcrzuk"),
"init": MustParseCid("bafk2bzacecbxp66q3ytjkg37nyv4rmzezbfaigvx4i5yhvqbm5gg4amjeaias"), "reward": MustParseCid("bafk2bzacebczbwfbbi6mvppbjcozatasjiaohvjjiqcy65ccuuyyw3xiixhk2"),
"multisig": MustParseCid("bafk2bzacecjltag3mn75dsnmrmopjow27buxqhabissowayqlmavrcfetqswc"), "storagemarket": MustParseCid("bafk2bzaceawqexy6t2ybzh3jjwhbs7icbg5vqnedbbge4e4r4pfp7spkcadsu"),
"paymentchannel": MustParseCid("bafk2bzacednzxg263eqbl2imwz3uhujov63tjkffieyl4hl3dhrgxyhwep6hc"), "storageminer": MustParseCid("bafk2bzacearemd7pn2jj26fdtqd4di27lfhpng3vp5chepm7qnmdzgiqr6wfi"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"), "storagepower": MustParseCid("bafk2bzaceddc7fiaxfobfegqaobf5xinjgmhsa5iu4yi6klvc3jmjimcdvgyg"),
"reward": MustParseCid("bafk2bzacectp23cxsbbdrr3uggnw7f263qll5wkkfzqhn5yq37ae2ehdjdzri"), "system": MustParseCid("bafk2bzacedylltr57b2n6zpadh4i2c2kis4fzzvhao3kgvfaggrrbqyacew7q"),
"storagemarket": MustParseCid("bafk2bzacea45ko3ezkpeujsniovncwnizc4wsxd7kyckskhs7gvzwthzb2mqe"), "verifiedregistry": MustParseCid("bafk2bzacecjkesz766626ab4svnzpq3jfs26a75vfktlfaku5fjdao2eyiqyq"),
"storageminer": MustParseCid("bafk2bzaced74qthwrl3gahcf7o3vrdrodbcqhlplh6fykbgy5sd2iyouhq44c"),
"storagepower": MustParseCid("bafk2bzaceduksv6wqthr5fgp7mx5prv6gzul2oozf3svrjbuggc4bgokdxgfy"),
"system": MustParseCid("bafk2bzacebe6j2ius6clbbr7dypsg54jzmn5xablzunph7ebedw6yhwla4cj2"),
"verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"),
}, },
}, { }, {
Network: "butterflynet", Network: "butterflynet",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacedsgi3wpyd46hbktrleolnlepzsm6k466fcrxuc7keht4guokgxiy"),
ManifestCid: MustParseCid("bafy2bzacec4tgdtsrgbdywc5nzf5ekiw5zuefrasiahb4n5yqwcrwjzcdp4nk"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebz7dm3vcuqtzzcf5jwvcubz6ecqk52t5rsd36fyzka2iosy4l4ro"), "account": MustParseCid("bafk2bzaceae6holtld4caox2xood5rpcjotrxj7lnfxvfmhivb3s2ddyj22qw"),
"cron": MustParseCid("bafk2bzacea6qtj2wkbe2wq5vxc2knlnj3vdvk4bkjp36xtazgzhnegd2uaj7m"), "cron": MustParseCid("bafk2bzaceab2vrkun6ps3hactaumfzgm6zk4sdasiqiedxzdttkvw64hndcdg"),
"datacap": MustParseCid("bafk2bzacedwxkx3jz7qwv5iwozadz7t5hhw5dtlgdxuwqxdp6oqguas7nakjk"), "datacap": MustParseCid("bafk2bzacecixx45mf6chwktsd2g5krlr35p3g7pkkrvzjeujz4ryhlztpl7fq"),
"eam": MustParseCid("bafk2bzacedoegh4idwvhjqahfnbqq6aqzgccgjwumudx6ihfut36ng57or7fi"), "eam": MustParseCid("bafk2bzaceciekaxrlgnmosmthbgptpdu2bzdoo7mt67p7cqbdvnxup6xpd6ns"),
"ethaccount": MustParseCid("bafk2bzacebn6l3x7d2i6lv72osbgcl4a37imexh5ou5kvbmj56taetwcyyhgq"), "ethaccount": MustParseCid("bafk2bzacecb4ttgbjzkaqrg7phqgao2kxsgeet4wnrr5qmftlfad26v6jpk4o"),
"evm": MustParseCid("bafk2bzaced5gaxg5mz3hho473aszx5brgjriicqgrcbqctnyyn2e6vcxv3ule"), "evm": MustParseCid("bafk2bzacecrwejr7bedjww67ppof3abb6df66w76r7wpuzc426arc4oibndeu"),
"init": MustParseCid("bafk2bzacecbo6ggprh7sz3oy6uu5raykwngqmnjdsiijdrgp4glet3mb65ywo"), "init": MustParseCid("bafk2bzacea5ke6q7je2ofrai7dpw67vat463d5f74g4evvwtcu7dhp4ff6ztk"),
"multisig": MustParseCid("bafk2bzacecmu3bhbg4rh5sqbagjlvrpb6ip5k3pngq22a33ok44yuhk75zenq"), "multisig": MustParseCid("bafk2bzacecs6aws25bvqmyzny3vcilr2xw35jymryu4yzodg7l7gf4bhjpolw"),
"paymentchannel": MustParseCid("bafk2bzacebth7fqe5xts6hbm7m6n733qcu6b6atd7ur6l7jhddferjgpxdy4s"), "paymentchannel": MustParseCid("bafk2bzacedtewkfsicz2rm4hsjsbagrl2mhmqfdikpsq3ggoct5iqa6caka6a"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaceds7hy7v77k2jsbkfob7b2qor6v5s2oancfxhkuuzwqqg6kxk27xe"), "reward": MustParseCid("bafk2bzacecqmh47zzzlzbtaueaz2fvhiqnktccfrcqicul4j6tca2bruvtn44"),
"storagemarket": MustParseCid("bafk2bzacebqi6ylwfmack3hfzw6eej7r6gwlbxzo33tdkfkpof7wg7h54pjtw"), "storagemarket": MustParseCid("bafk2bzacecbvqe4k6jyvwovxfnkylj3zpb2vjxkc3ar53x7c2pe5mkokxuyk6"),
"storageminer": MustParseCid("bafk2bzacedsxpkqqiycn5tjydycnlqer4544mpqvtwfamwyq6hwz7yjqd3iry"), "storageminer": MustParseCid("bafk2bzaceczbh2aofwcif4aqycydmnsjkkww4i4yfl4zca5j2dqopbz46dvrg"),
"storagepower": MustParseCid("bafk2bzacedssirrse7ufxti6capgf2qufb6y3oatv2fnnnh7xrgp47x3hfox4"), "storagepower": MustParseCid("bafk2bzacealioyiirrvov5rnh63omtsifppcsgba7my2tp7bslhd454wczepy"),
"system": MustParseCid("bafk2bzacea2lod7lxod72voxyik5btpzmpvduddr4hwshcsyyy257izh6kut4"), "system": MustParseCid("bafk2bzaceax2qvj3ap2dxvzgjps2vtmfgfrej3hdgk7a5euqdgsmak7ptalaa"),
"verifiedregistry": MustParseCid("bafk2bzacebss7ol4ay6nkg7r3c2355aqpku4yvqipyh3sgdrxkhsrssrsaaig"), "verifiedregistry": MustParseCid("bafk2bzaceaeqg3nqpjrgklq6nli6hz73s76hp4bwn6jsa64y22dj3csvmcl32"),
}, },
}, { }, {
Network: "calibrationnet", Network: "calibrationnet",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacedrdn6z3z7xz7lx4wll3tlgktirhllzqxb766dxpaqp3ukxsjfsba"), ManifestCid: MustParseCid("bafy2bzacedrdn6z3z7xz7lx4wll3tlgktirhllzqxb766dxpaqp3ukxsjfsba"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecruossn66xqbeutqx5r4k2kjzgd43frmwd4qkw6haez44ubvvpxo"), "account": MustParseCid("bafk2bzacecruossn66xqbeutqx5r4k2kjzgd43frmwd4qkw6haez44ubvvpxo"),
@ -92,6 +92,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "calibrationnet", Network: "calibrationnet",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzacedbedgynklc4dgpyxippkxmba2mgtw7ecntoneclsvvl4klqwuyyy"), ManifestCid: MustParseCid("bafy2bzacedbedgynklc4dgpyxippkxmba2mgtw7ecntoneclsvvl4klqwuyyy"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceavfgpiw6whqigmskk74z4blm22nwjfnzxb4unlqz2e4wg3c5ujpw"), "account": MustParseCid("bafk2bzaceavfgpiw6whqigmskk74z4blm22nwjfnzxb4unlqz2e4wg3c5ujpw"),
@ -110,28 +111,30 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "calibrationnet", Network: "calibrationnet",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacec4ilfymf3sorrfxp67ruwbax3a4mbqzic63vy2xlfh3ulky3bxvs"),
ManifestCid: MustParseCid("bafy2bzaced25ta3j6ygs34roprilbtb3f6mxifyfnm7z7ndquaruxzdq3y7lo"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecupizfd6xbts7blvn3ozouy3f2gtehwl7qohjks54nsomtzs3aki"), "account": MustParseCid("bafk2bzacebhfuz3sv7duvk653544xsxhdn4lsmy7ol7k6gdgancyctvmd7lnq"),
"cron": MustParseCid("bafk2bzacedry7eqweymdnybq5jm5slizm67v4ffhv7zqiw2jwevr7ijv25gjc"), "cron": MustParseCid("bafk2bzacecw2yjb6ysieffa7lk7xd32b3n4ssowvafolt7eq52lp6lk4lkhji"),
"datacap": MustParseCid("bafk2bzacebq6vigteuwchk7si6y45ogrfu2zpxjbo4a54btnbhp3rc3ifghx6"), "datacap": MustParseCid("bafk2bzaceaot6tv6p4cat3cg5fknq22htosw3p5rwyijmdsraatwqyc4qyero"),
"eam": MustParseCid("bafk2bzacebounosssmuaz35xpyuupvijbcwqyaumbeztqmigbihfw2ysbnx4w"), "eam": MustParseCid("bafk2bzacec5untyj6cefdsfm47wckozw6wt6svqqh5dzh63nu4f6dvf26fkco"),
"ethaccount": MustParseCid("bafk2bzacebi2ymbi5wo2o3rp2x6cqo55vroixngmpbdcs7el4rq4hvacyzsqy"), "ethaccount": MustParseCid("bafk2bzacebiyrhz32xwxi6xql67aaq5nrzeelzas472kuwjqmdmgwotpkj35e"),
"evm": MustParseCid("bafk2bzaceapklwjzdzkmnfprn5wsjdzjnueuw2ke4kixq46gnbwjncns4dleu"), "evm": MustParseCid("bafk2bzaceblpgzid4qjfavuiht6uwvq2lznshklk2qmf5akm3dzx2fczdqdxc"),
"init": MustParseCid("bafk2bzaced7u4zpkxh5ecjo2emwsrk3vnickhmkxy22garqf766nbxcewymy6"), "init": MustParseCid("bafk2bzacedhxbcglnonzruxf2jpczara73eh735wf2kznatx2u4gsuhgqwffq"),
"multisig": MustParseCid("bafk2bzacedlunqzd3mxslb7zej5fsti2jxredfhtcqqxepng67t4zfiv6lwlc"), "multisig": MustParseCid("bafk2bzacebv5gdlte2pyovmz6s37me6x2rixaa6a33w6lgqdohmycl23snvwm"),
"paymentchannel": MustParseCid("bafk2bzacea4z2yi33rfiiutkmqko33fslikmeqgypkiam5cqpeylyp3oup552"), "paymentchannel": MustParseCid("bafk2bzacea7ngq44gedftjlar3j3ql3dmd7e7xkkb6squgxinfncybfmppmlc"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzacea4dnvun5vwzunhgepejrknukx2di2kmo3x4akz6rollq5icsrl3m"), "reward": MustParseCid("bafk2bzacea3yo22x4dsh4axioshrdp42eoeugef3tqtmtwz5untyvth7uc73o"),
"storagemarket": MustParseCid("bafk2bzaceafoon3fsl756rbrih4upar3ayi6746gaj756bk56thncpotl4coa"), "storagemarket": MustParseCid("bafk2bzacecclsfboql3iraf3e66pzuh3h7qp3vgmfurqz26qh5g5nrexjgknc"),
"storageminer": MustParseCid("bafk2bzacea3dj37h74ue2jtief3bj2shxagigygcm2h6purgp42mr6swwfdiw"), "storageminer": MustParseCid("bafk2bzacedu4chbl36rilas45py4vhqtuj6o7aa5stlvnwef3kshgwcsmha6y"),
"storagepower": MustParseCid("bafk2bzacebmodckd4tustgfmeilcfi3ovd4wzxz2hnd6vyhkq7hgiojiy3cc6"), "storagepower": MustParseCid("bafk2bzacedu3c67spbf2dmwo77ymkjel6i2o5gpzyksgu2iuwu2xvcnxgfdjg"),
"system": MustParseCid("bafk2bzacebpqirxha42noejsk5miv5kip44eay6lm63pxt26xhlwdmn7tnqaq"), "system": MustParseCid("bafk2bzacea4mtukm5zazygkdbgdf26cpnwwif5n2no7s6tknpxlwy6fpq3mug"),
"verifiedregistry": MustParseCid("bafk2bzaceczf7qrddwt5kh3gvro25wpls346tanffeatk7nsczjnwb7jtd454"), "verifiedregistry": MustParseCid("bafk2bzacec67wuchq64k7kgrujguukjvdlsl24pgighqdx5vgjhyk6bycrwnc"),
}, },
}, { }, {
Network: "caterpillarnet", Network: "caterpillarnet",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"),
@ -154,6 +157,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "caterpillarnet", Network: "caterpillarnet",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"),
@ -176,28 +180,30 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "caterpillarnet", Network: "caterpillarnet",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacec36gpvghhgjwa5ya3ocxg33pct2vddegeixgkpqsc6eiyajdjkii"),
ManifestCid: MustParseCid("bafy2bzacedn6med544h6r7frzvyq5cvd7dqgnwgpmzgf42d4agoysx6tf475i"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebcl3xlk7i6t5tau2rfgxft5pu6qzvjqxo6zs5guerz3xarxztyv6"), "account": MustParseCid("bafk2bzaceaysjus6ldo45qnedaopwctamtvvk4ga2l4dh7dmdtltsfin4puuk"),
"cron": MustParseCid("bafk2bzacebhoqjvaxtzj3k4tz7c4vtt4or4u3h3jhwxlh3t4l6by2ota3s7by"), "cron": MustParseCid("bafk2bzaceatq2ltzs2p37nniek3qpkitzlfd7iu2qtupzjtgvtggxglrhj7ay"),
"datacap": MustParseCid("bafk2bzaceb7ttn3d43yb7l5ok5rjgr7325jb6ds4air7mivgoyzp5p4gwgrq4"), "datacap": MustParseCid("bafk2bzacecgwe56okusbtsfimiwstxe7ova25uvrkj4osk3w5wl2qclvd64bi"),
"eam": MustParseCid("bafk2bzacebobuasaev75fge6xg6bekrdvnyox4h7iluupt4wqq2n4expha2oe"), "eam": MustParseCid("bafk2bzaceak3xbmmyj5glnm65kv5p7zc6u7x2xallwpz7aphqqouadn3jvumm"),
"ethaccount": MustParseCid("bafk2bzaceaghtv45mm6qx3yrxwy7zz7x7mqj4n4lzw4hx7zxzlij6dcxxuv4c"), "ethaccount": MustParseCid("bafk2bzacec5bcn2i4ktsc54wx7gf4gwdd6xjcukh43szfya47jicxlwrhfrhk"),
"evm": MustParseCid("bafk2bzacecu7xpnpw27jquvnpfv4rseaal477ml4ouxy37eo7wymgfzkexllg"), "evm": MustParseCid("bafk2bzacebbc2iv4tw2kfmmcm7k3uxilpqvbjg6jsqbov4n7wqcxvvmtazfbc"),
"init": MustParseCid("bafk2bzacea2rnkho4nliqvisiqgtqx66c4xneagpgj52tyqa64grxadggylbk"), "init": MustParseCid("bafk2bzacecvlqa2szdyem4gwgks2yk7bfernmzbxgo5felnpqgikyesdyiury"),
"multisig": MustParseCid("bafk2bzacebak6spthfa23cyqjmpgkgku4gg4egdn2zc6vkikbh5ongadzakma"), "multisig": MustParseCid("bafk2bzacebvqjxop2ald5f5hvu7qqb7ali7iluxcbdd3ssllawco6kafjteqw"),
"paymentchannel": MustParseCid("bafk2bzaceb3tib72pwze2rov72ldwlfv3otes3tejgnfpbrzahwb5xi7slhqm"), "paymentchannel": MustParseCid("bafk2bzacebux5gmkddtur2kfebwzrxwqyqh2almlt4bw3v7f4bg3gy2zqjhbe"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaceak3n3orgdraub4bqiy3paio77hu4laaqv4vf7wmwv4ybl5ahgi5o"), "reward": MustParseCid("bafk2bzacebhm5w7q7wlxrwgbldolzq5qfcdmcu66j6ty37ppvpwafxzlizxn4"),
"storagemarket": MustParseCid("bafk2bzacearo7sog7yqbrwyws5o3lbsdsjf2cp5vsoxc4u3s5atgjtwzzh65s"), "storagemarket": MustParseCid("bafk2bzacebgniq7x22ep4oiithvlzepxo5jsvhuang2vqfz3prozihmviw5ey"),
"storageminer": MustParseCid("bafk2bzacecrzmjrbqjwknnkybdexspb6gfu4q6dvtaeguxl26yuytsjc3w7ws"), "storageminer": MustParseCid("bafk2bzacecchnrfi4cgbpis4aagiqkhalgqudjlu25da7rer4ltlgpojersgm"),
"storagepower": MustParseCid("bafk2bzaceavlmlu4mt2u7xwnnzf6vwdmh2yo76aauujwlgsbfhafjgxb4zgtg"), "storagepower": MustParseCid("bafk2bzaceaxomr5xbhacbbn5ib6unekjz6igoqr4r4a2taxqcpyb4gpwi6zvk"),
"system": MustParseCid("bafk2bzacec35rgzpiaa4n3r5bzgssk33bhfgozjvgunbwax32dooqqokfe6ag"), "system": MustParseCid("bafk2bzacebmymcxtwkk6dzgtmkbradncjpsxdqkcwtemhio5acvpm742rguv6"),
"verifiedregistry": MustParseCid("bafk2bzacebjfkrzihgzlb2jecgm5seoqwf5e656zc22vjoyclioru6vdy2bnm"), "verifiedregistry": MustParseCid("bafk2bzaceae5zbc2h6gpyu6uzsvelvww53p5mujq2dvs3zi74w6mvnigwc3va"),
}, },
}, { }, {
Network: "devnet", Network: "devnet",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacedq7tuibavyqxzkq4uybjj7ly22eu42mjkoehwn5d47xfunmtjm4k"), ManifestCid: MustParseCid("bafy2bzacedq7tuibavyqxzkq4uybjj7ly22eu42mjkoehwn5d47xfunmtjm4k"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacea4tlgnp7m6tlldpz3termlwxlnyq24nwd4zdzv4r6nsjuaktuuzc"), "account": MustParseCid("bafk2bzacea4tlgnp7m6tlldpz3termlwxlnyq24nwd4zdzv4r6nsjuaktuuzc"),
@ -215,6 +221,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "devnet", Network: "devnet",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk"), ManifestCid: MustParseCid("bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaced5llqnqqhypolyuogz3h2wjomugqkrhyhocvly3aoib4c5xiush6"), "account": MustParseCid("bafk2bzaced5llqnqqhypolyuogz3h2wjomugqkrhyhocvly3aoib4c5xiush6"),
@ -233,50 +240,30 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "devnet", Network: "devnet",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacebemt6rdgtsj5vhv2iimbdvm5g4xllgl7nugxvuuthsedncmfakww"),
ManifestCid: MustParseCid("bafy2bzaceco52tjbexpijsegolhdkhlziflum4bl27hcjrpnny273t3lsa6tc"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceajmds6zbz235lbjjhv3mxc6x3kqudjkxedh5xqvlemh3f6xslz76"), "account": MustParseCid("bafk2bzacec6mdvynyu4cxb53tcdbkcu7w7jzxduxqqadi2y2rx2tsm42627tk"),
"cron": MustParseCid("bafk2bzaceabbv5ej2yd3n7txl3s4pahknb4in5dok57hzwfheqnk6k67zegbk"), "cron": MustParseCid("bafk2bzaceaiscwdpdzdooja7hwz56ee3zztjogl4gljkccpefi7uliqtaq2ek"),
"datacap": MustParseCid("bafk2bzaceayzgq7qpuc5pr4lrh6k3xnvmirlmutffplmgur4pvcaynpxlkph6"), "datacap": MustParseCid("bafk2bzacedmfwrwwqmwxtfpvhp33mvt5btq2ewbjfrvfetwnrxt5r37i3ymzk"),
"eam": MustParseCid("bafk2bzacecrand7mp7q3jm3u5dpqm4o24ki3pk3uzcw4zonjcowq4rxwptsis"), "eam": MustParseCid("bafk2bzaced2lwwrqtkgwxdgadpdbxpxjoh2gsunjg3bgtoubs47p7fbktbu26"),
"ethaccount": MustParseCid("bafk2bzacecpwfxpvqiyiisbfw45v5ottcstxu2vifji3xswxt3jzk4vcrs4g4"), "ethaccount": MustParseCid("bafk2bzacea5zob56gdcxudkubhol4gijzgwgtaaix4pmv3vpg4ihtsuxbdhqa"),
"evm": MustParseCid("bafk2bzaceajrtntc5urxkwbzdu3khi2eqvarnfx6vh7luqt33gn6z4a4kjkj6"), "evm": MustParseCid("bafk2bzaceacw53ajmggrugzfiag75suv27hvqoduypk24xru3cumctpxotbya"),
"init": MustParseCid("bafk2bzaced6npj5zrjb3lxhgtsq4st66dvde56nftbvchmpid3rcazfvnqkpk"), "init": MustParseCid("bafk2bzaceahgtz6647nbarvyjwtvjadzd2i2m75jv6nnrq3kgwrjxnvkykmhs"),
"multisig": MustParseCid("bafk2bzacealhbd4slci4o76dpdurkkk3q5busopediwfh7uis4hfh7tzghzni"), "multisig": MustParseCid("bafk2bzaceduhknhgd45j5aey7c7pszbbwqm4vuih4iwbuffjxekqteebuja5q"),
"paymentchannel": MustParseCid("bafk2bzacebvpkvrihus53sdyutsjsbpfefe5gd2amfb6zkztdfp6g2m4ubqrk"), "paymentchannel": MustParseCid("bafk2bzacec5x44xqfgmdvsxr4nwzbcwaotodzffsjsslw64xblr7xgx7jr6c4"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaceaftaidppnno2dzhpxl5vyti5mcmdhvheieanwvptgacuj5ozzloe"), "reward": MustParseCid("bafk2bzacebzyuwya26rjjxmtzcszf5hcv54b3l7bz6hbflbx3wmpycbqcq6fa"),
"storagemarket": MustParseCid("bafk2bzacea75td2k2cdwc2o4kotdods2thomhcoqg5rf62ty6gkuxojknziae"), "storagemarket": MustParseCid("bafk2bzaceav2nt4ek457u3ngn7da2gaqblwdumpzhsohp4d7whmubvarkllac"),
"storageminer": MustParseCid("bafk2bzaceapj5q7egywl3zovwcm4hpbvr4vjtoshj57ncqg3srzseweyclvug"), "storageminer": MustParseCid("bafk2bzacecxr3rdjaive7opvfyqv3p7tft6ragdozlqd6hciprlknda7u5hk6"),
"storagepower": MustParseCid("bafk2bzacebbraebsoin6hhmr4na56st4gyg7yd7p2ry2igegnvws7deq32hec"), "storagepower": MustParseCid("bafk2bzaceabvb7af55pgm3xpcc7lqjaupw3dyyokbmhjvbo2ebelizalmugfq"),
"system": MustParseCid("bafk2bzacedtw3mq5zyxxbnybnjegqyrz3ufiboeoipyzynlk6zgyumvl3267g"), "system": MustParseCid("bafk2bzacecp7sswldmz6cbl7lh6y5vtwnn43mvdkgcazcyjjcpjjbtydb2f3w"),
"verifiedregistry": MustParseCid("bafk2bzacecaqciqoky2z7win5rkzd3gkgpa3345adjyiidmg4swmw5celeb3a"), "verifiedregistry": MustParseCid("bafk2bzaced27273xjvuyhxlne2kmbrbtupcxxpdchqbkiyr3dcqoijaok2k7e"),
}, },
}, { }, {
Network: "hyperspace", Network: "hyperspace",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"),
Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"),
"cron": MustParseCid("bafk2bzaceahgq64awp4f7li3hdgimc4upqvdvltpmeywckvens33umcxt424a"),
"datacap": MustParseCid("bafk2bzacebkxn52ttooaslkwncijk3bgd3tm2zw7vijdhwvg2cxnxbrzmmq5e"),
"eam": MustParseCid("bafk2bzaceczhgub5anrnaf7ol65mu54gsgwcj6c6m3yhet7rhxm2l6kz4s4ru"),
"ethaccount": MustParseCid("bafk2bzacealn5enbxyxbfs7gbsjbyma2zk3bcr7okvflxhpr753d4eh6ixooa"),
"evm": MustParseCid("bafk2bzacedljkrmazyewawpnddrkzrt55556374dw2pm2hokgkompgzw4vx5y"),
"init": MustParseCid("bafk2bzacec55gyyaqjrw7zughywocgwcjvv6k5fijjpjw4xgckuqz6pjtff5a"),
"multisig": MustParseCid("bafk2bzaceblozbdzybdivvjdiid4jwm2jc6x5a66sunh2vvwsqba6wzqmr7i6"),
"paymentchannel": MustParseCid("bafk2bzacealcyke5a6n24efs6qe4iikynpk2twqssyugy7jcyf6p6shgw2iwa"),
"placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"),
"reward": MustParseCid("bafk2bzacebafzaqhwsm3nmsfwcd6ngvx6ev6zlcpyfljqh4kb77vok6opban6"),
"storagemarket": MustParseCid("bafk2bzacecrjfg4p7fxznsdkoobs4po2ve3ywixrirrk6netgxh63qqaefamg"),
"storageminer": MustParseCid("bafk2bzaceb3ctd4atxwhdkmlg4i63zxo5aopknlj7l5kaiqr22xpcmico6vg4"),
"storagepower": MustParseCid("bafk2bzacecvcix3ugopvby2vah5wwiu5cqjedwzwkanmr34kdoc4f3o6p7nsq"),
"system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"),
"verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"),
},
}, {
Network: "hyperspace",
Version: 9,
ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"), ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"),
@ -299,6 +286,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "mainnet", Network: "mainnet",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacebogjbpiemi7npzxchgcjjki3tfxon4ims55obfyfleqntteljsea"), ManifestCid: MustParseCid("bafy2bzacebogjbpiemi7npzxchgcjjki3tfxon4ims55obfyfleqntteljsea"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacedudbf7fc5va57t3tmo63snmt3en4iaidv4vo3qlyacbxaa6hlx6y"), "account": MustParseCid("bafk2bzacedudbf7fc5va57t3tmo63snmt3en4iaidv4vo3qlyacbxaa6hlx6y"),
@ -316,6 +304,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "mainnet", Network: "mainnet",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i"), ManifestCid: MustParseCid("bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacect2p7urje3pylrrrjy3tngn6yaih4gtzauuatf2jllk3ksgfiw2y"), "account": MustParseCid("bafk2bzacect2p7urje3pylrrrjy3tngn6yaih4gtzauuatf2jllk3ksgfiw2y"),
@ -334,28 +323,30 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "mainnet", Network: "mainnet",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacec2ggeabyyl2cjaqmcpnyvjirrrm6bfc7d73q4pekm27hybzdqs3q"),
ManifestCid: MustParseCid("bafy2bzacecyg4biu2uccoekdzen4qxf4qt24deyx6j5rpwfys7qp6lixvzsxo"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebdlwwnd57vd2444wrfe5amtf2f6htqj3hdh4fxblywdbynrurhgy"), "account": MustParseCid("bafk2bzacect72amqxedrtjymuq5lfrskk2itnniyfa5gdvqp5sjoeeb33oi2e"),
"cron": MustParseCid("bafk2bzacecxmaxh272zhgmayfg7btvq5lshv2cd7njkarlbbikba4otiaboyg"), "cron": MustParseCid("bafk2bzaceb3nfsu5jbftadzxy24caz4tlgi6476yml25tfq2g7higtgnifys4"),
"datacap": MustParseCid("bafk2bzaceb64wicovvrjzaotvs64hmdtvolw4l6qanwp5tk56okzqbfttxck2"), "datacap": MustParseCid("bafk2bzacec3s7oovwjxdx3hnhtqr75fsvhj7p4545gedt3kf2iuaw7zqhym2c"),
"eam": MustParseCid("bafk2bzacedxs56zywfumzcv7i5fwluku2qevg54cuiuwi5d3pavf3rilfu33g"), "eam": MustParseCid("bafk2bzacebw4ye6kvufarvrtqebs57idw6ydtzli7egd4h2t33jwoi547trra"),
"ethaccount": MustParseCid("bafk2bzacecepsmgsucfebvbwf5vebm7j6zeqaz3ub52warxqobqeymh5vdjik"), "ethaccount": MustParseCid("bafk2bzaceavrimh4mcla6zi25uhs3ystix2n5rp4kfqeiewkh337zpjbo3egq"),
"evm": MustParseCid("bafk2bzacecf6arqbso67nmrhcsjvyradrbbv7hs2noand27fyr4nfilms4znu"), "evm": MustParseCid("bafk2bzacecnsk2ydh2q6wxf2fzsvivo6cfrka3jos62io2ds2xou4gl2byqvw"),
"init": MustParseCid("bafk2bzaceat2xcem5lko5ot4mmrowtm6ehx5klw7c4ss4vxma55tyfvvxwlge"), "init": MustParseCid("bafk2bzacebb3l4gw6hfszizw5zwho3pfpnmgrmxqm4ie42dgn62325lo4vwc2"),
"multisig": MustParseCid("bafk2bzacebz43omxi5vtkidhsxroqtgkpxtftdj6poew3744fayfftgdebe4y"), "multisig": MustParseCid("bafk2bzacedi6ii3ewygygjukn4viros3uiztonnf6tg6b3ppqk4pdtqrwgeuw"),
"paymentchannel": MustParseCid("bafk2bzaceds4ob3ev2ie2vorhfomddd44otqfau4d4eogfofjjbjjx2h27nh2"), "paymentchannel": MustParseCid("bafk2bzacebwqqfhodha2jl7tbws3dpy2dkngepbllqx6hy72zdokui3ow6eeq"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaced7xvqx7n6426lls4ao54exn63pv73m7makxf7ygb575roqxhjuuw"), "reward": MustParseCid("bafk2bzacedbeexrv2d4kiridcvqgdatcwo2an4xsmg3ckdrptxu6c3y7mm6ji"),
"storagemarket": MustParseCid("bafk2bzaceb5piewkvdj4ee6b4qzhimixjzee5z3hsuwdjksncpvef7sgaw6rw"), "storagemarket": MustParseCid("bafk2bzacedalaigmokrtimabt7y7bkok5nd2j5gmifdahht3dsz5ulj7vxdgu"),
"storageminer": MustParseCid("bafk2bzaceacukfushmnsqtdvtdyx2in6o2el7jq46qo7iaxgwytel4oz5srv4"), "storageminer": MustParseCid("bafk2bzacecpq5wjp3frz3b4cd2pozegi7sykgcawnaowjm6ddyai2epbphxvw"),
"storagepower": MustParseCid("bafk2bzacedi6z45jcms5guns4qxi6rs2e2prc6mpnhkr4klljrra3ayfburss"), "storagepower": MustParseCid("bafk2bzacedfxlpyj5uxlh5uuhl55lazmhm7q6pr3qoywxb25qrytbptpy7zb6"),
"system": MustParseCid("bafk2bzacedy7ssu2hez3nu7bi4j6ucojty4sfaublxlxhfd3tkgzyrm5sdxbq"), "system": MustParseCid("bafk2bzacecbscw26oyfgdse6y6ij5fqtaq5uo2ehfom26mle4rk4ann2xf2jq"),
"verifiedregistry": MustParseCid("bafk2bzacecjgudirfyzyroq3xhf2bldl636w7prexcvo7v3xqdijzcom4rgry"), "verifiedregistry": MustParseCid("bafk2bzaceanpda37bvefmzfemikyokwnspzxdxqz5kriaqex4hpevdhphu6sq"),
}, },
}, { }, {
Network: "testing", Network: "testing",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacedkjpqx27wgsvfxzuxfvixuxtbpt2y6yo6igcasez6gqiowron776"), ManifestCid: MustParseCid("bafy2bzacedkjpqx27wgsvfxzuxfvixuxtbpt2y6yo6igcasez6gqiowron776"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"),
@ -373,6 +364,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "testing", Network: "testing",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzacecnnrmekqw2xvud46g3vo6x26cogh3ydgljqajlxqxzzbuxsjlwjm"), ManifestCid: MustParseCid("bafy2bzacecnnrmekqw2xvud46g3vo6x26cogh3ydgljqajlxqxzzbuxsjlwjm"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"),
@ -391,28 +383,30 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "testing", Network: "testing",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzacedhivj4zbumou6d3242p3ecqhlqfcjfskdv46uzjchlj3ve23xyoa"),
ManifestCid: MustParseCid("bafy2bzacedjgfy7dmbd4i3io5r47eokprndhucdvwaxqyw4ijhhtldhewojk4"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"),
"cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"),
"datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"),
"eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"),
"ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"),
"evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"),
"init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"),
"multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"),
"paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"),
"storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"),
"storageminer": MustParseCid("bafk2bzacecx2fs3ra4ydxvwq6oh73esqy2xjqhwsnfrdl5ctbg26zem77zy3u"), "storageminer": MustParseCid("bafk2bzacednqbtebg7xxsr2sle42pfxmz5chxn32bsjssgc3mzt7iw2eevaly"),
"storagepower": MustParseCid("bafk2bzacedwfnzestwv7ylleeuk3fhp6jewc4ygw3fgodsciww7gw5ilt4ony"), "storagepower": MustParseCid("bafk2bzacebovido4zxtywaz32ejagvtk4v7z5w5nwxrflaldsf56xd7pecu4w"),
"system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"),
"verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"),
}, },
}, { }, {
Network: "testing-fake-proofs", Network: "testing-fake-proofs",
Version: 8, Version: 8,
ManifestCid: MustParseCid("bafy2bzacecd3lb5v6tzjylnhnrhexslssyaozy6hogzgpkhztoe76exbrgrug"), ManifestCid: MustParseCid("bafy2bzacecd3lb5v6tzjylnhnrhexslssyaozy6hogzgpkhztoe76exbrgrug"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"),
@ -430,6 +424,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "testing-fake-proofs", Network: "testing-fake-proofs",
Version: 9, Version: 9,
ManifestCid: MustParseCid("bafy2bzacecql2gj2tri4fnbznmldue73qzt6zszvugw4exd64mwb52zrhv7k2"), ManifestCid: MustParseCid("bafy2bzacecql2gj2tri4fnbznmldue73qzt6zszvugw4exd64mwb52zrhv7k2"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"),
@ -448,23 +443,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
}, { }, {
Network: "testing-fake-proofs", Network: "testing-fake-proofs",
Version: 10, Version: 10,
ManifestCid: MustParseCid("bafy2bzaceav36pezxhapk6vlgohdp6jiydk44o6xowltjnyhu3nrhpfcby5zs"),
ManifestCid: MustParseCid("bafy2bzaceblvi7d3yosakpuux27gqzr34gcjr6a2f6uzbyagmwybgfsk4xeu2"),
Actors: map[string]cid.Cid{ Actors: map[string]cid.Cid{
"account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"),
"cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"),
"datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"),
"eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"),
"ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"),
"evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"),
"init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"),
"multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"),
"paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"),
"placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"),
"reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"),
"storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"),
"storageminer": MustParseCid("bafk2bzacebp3rj6d4g2ppngw2xp7okzqx6oapfk6xi54n3aqenadqvptlk45g"), "storageminer": MustParseCid("bafk2bzaceaoaduzssj46mse6gizcy764ingsgvuavafkowf4vexluindct3ji"),
"storagepower": MustParseCid("bafk2bzacedhwtksxb6orm63doxx2bgcy6fpy5li5prjb3twsxdh75anjbmdug"), "storagepower": MustParseCid("bafk2bzacedqvicpfdcegfsj6p4rb3judx7v5v6trpnca7djbim4pts5appis4"),
"system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"),
"verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"),
}, },
}} }}

View File

@ -17,7 +17,13 @@ func TestEmbeddedMetadata(t *testing.T) {
metadata, err := build.ReadEmbeddedBuiltinActorsMetadata() metadata, err := build.ReadEmbeddedBuiltinActorsMetadata()
require.NoError(t, err) 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. // Test that we're registering the manifest correctly.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -19,7 +19,7 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{
0: DrandMainnet, 0: DrandMainnet,
} }
const GenesisNetworkVersion = network.Version16 const GenesisNetworkVersion = network.Version17
var NetworkBundle = "butterflynet" var NetworkBundle = "butterflynet"
var BundleOverrides map[actorstypes.Version]string var BundleOverrides map[actorstypes.Version]string

View File

@ -49,4 +49,8 @@ type State interface {
Nonce() (uint64, error) Nonce() (uint64, error)
GetState() interface{} GetState() interface{}
GetBytecode() ([]byte, error)
GetBytecodeCID() (cid.Cid, error)
GetBytecodeHash() ([32]byte, error)
} }

View File

@ -49,4 +49,8 @@ type State interface {
Nonce() (uint64, error) Nonce() (uint64, error)
GetState() interface{} GetState() interface{}
GetBytecode() ([]byte, error)
GetBytecodeCID() (cid.Cid, error)
GetBytecodeHash() ([32]byte, error)
} }

View File

@ -43,3 +43,25 @@ func (s *state{{.v}}) Nonce() (uint64, error) {
func (s *state{{.v}}) GetState() interface{} { func (s *state{{.v}}) GetState() interface{} {
return &s.State return &s.State
} }
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
}

View File

@ -3,6 +3,7 @@ package evm
import ( import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/filecoin-project/go-state-types/abi"
evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm" evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm"
"github.com/filecoin-project/lotus/chain/actors/adt" "github.com/filecoin-project/lotus/chain/actors/adt"
@ -43,3 +44,25 @@ func (s *state10) Nonce() (uint64, error) {
func (s *state10) GetState() interface{} { func (s *state10) GetState() interface{} {
return &s.State 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
}

View File

@ -92,11 +92,11 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
}() }()
ctx = blockstore.WithHotView(ctx) 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{ vmopt := &vm.VMOpts{
StateBase: base, StateBase: base,
Epoch: e, Epoch: e,
Timestamp: ts.MinTimestamp(), Timestamp: timestamp,
Rand: r, Rand: r,
Bstore: sm.ChainStore().StateBlockstore(), Bstore: sm.ChainStore().StateBlockstore(),
Actors: NewActorRegistry(), Actors: NewActorRegistry(),
@ -142,10 +142,22 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context,
return nil 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++ { for i := parentEpoch; i < epoch; i++ {
var err error var err error
if i > parentEpoch { 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 { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making cron vm: %w", err) 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()
partDone = metrics.Timer(ctx, metrics.VMApplyMessages) partDone = metrics.Timer(ctx, metrics.VMApplyMessages)
vmi, err := makeVmWithBaseStateAndEpoch(pstate, epoch) vmi, err := makeVm(pstate, epoch, ts.MinTimestamp())
if err != nil { if err != nil {
return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err) return cid.Undef, cid.Undef, xerrors.Errorf("making vm: %w", err)
} }

View File

@ -105,18 +105,9 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever
continue 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 // event matches filter, so record it
cev := &CollectedEvent{ cev := &CollectedEvent{
Entries: entries, Entries: ev.Entries,
EmitterAddr: addr, EmitterAddr: addr,
EventIdx: evIdx, EventIdx: evIdx,
Reverted: revert, Reverted: revert,

View File

@ -287,6 +287,7 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event {
ev.Entries = append(ev.Entries, types.EventEntry{ ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x01, Flags: 0x01,
Key: in.k, Key: in.k,
Codec: cid.Raw,
Value: in.v, 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{ ev.Entries = append(ev.Entries, types.EventEntry{
Flags: 0x00, Flags: 0x00,
Key: in.k, Key: in.k,
Codec: cid.Raw,
Value: in.v, Value: in.v,
}) })
} }

View File

@ -47,6 +47,7 @@ var ddls = []string{
indexed INTEGER NOT NULL, indexed INTEGER NOT NULL,
flags BLOB NOT NULL, flags BLOB NOT NULL,
key TEXT NOT NULL, key TEXT NOT NULL,
codec INTEGER,
value BLOB NOT NULL value BLOB NOT NULL
)`, )`,
@ -67,8 +68,8 @@ const (
VALUES(?, ?, ?, ?, ?, ?, ?, ?)` VALUES(?, ?, ?, ?, ?, ?, ?, ?)`
insertEntry = `INSERT OR IGNORE INTO event_entry insertEntry = `INSERT OR IGNORE INTO event_entry
(event_id, indexed, flags, key, value) (event_id, indexed, flags, key, codec, value)
VALUES(?, ?, ?, ?, ?)` VALUES(?, ?, ?, ?, ?, ?)`
) )
type EventIndex struct { type EventIndex struct {
@ -194,6 +195,7 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever
isIndexedValue(entry.Flags), // indexed isIndexedValue(entry.Flags), // indexed
[]byte{entry.Flags}, // flags []byte{entry.Flags}, // flags
entry.Key, // key entry.Key, // key
entry.Codec, // codec
entry.Value, // value entry.Value, // value
) )
if err != nil { if err != nil {
@ -251,7 +253,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
subclauses := []string{} subclauses := []string{}
for _, val := range vals { for _, val := range vals {
subclauses = append(subclauses, fmt.Sprintf("%s.value=?", joinAlias)) subclauses = append(subclauses, fmt.Sprintf("%s.value=?", joinAlias))
values = append(values, trimLeadingZeros(val)) values = append(values, val)
} }
clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")") clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")")
} }
@ -270,6 +272,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
event.reverted, event.reverted,
event_entry.flags, event_entry.flags,
event_entry.key, event_entry.key,
event_entry.codec,
event_entry.value event_entry.value
FROM event JOIN event_entry ON event.id=event_entry.event_id` 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 reverted bool
flags []byte flags []byte
key string key string
codec uint64
value []byte value []byte
} }
@ -334,6 +338,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
&row.reverted, &row.reverted,
&row.flags, &row.flags,
&row.key, &row.key,
&row.codec,
&row.value, &row.value,
); err != nil { ); err != nil {
return xerrors.Errorf("read prefill row: %w", err) 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{ ce.Entries = append(ce.Entries, types.EventEntry{
Flags: row.flags[0], Flags: row.flags[0],
Key: row.key, Key: row.key,
Codec: row.codec,
Value: row.value, Value: row.value,
}) })
@ -398,12 +404,3 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error {
return nil return nil
} }
func trimLeadingZeros(b []byte) []byte {
for i := range b {
if b[i] != 0 {
return b[i:]
}
}
return []byte{}
}

View File

@ -13,13 +13,11 @@ import (
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "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/api"
"github.com/filecoin-project/lotus/chain/messagepool" "github.com/filecoin-project/lotus/chain/messagepool"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/chain/wallet/key"
"github.com/filecoin-project/lotus/node/modules/dtypes" "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 // Sign the message with the nonce
msg.Nonce = nonce msg.Nonce = nonce
keyInfo, err := ms.wallet.WalletExport(ctx, msg.From) sb, err := SigningBytes(msg, msg.From.Protocol())
if err != nil {
return nil, err
}
sb, err := SigningBytes(msg, key.ActSigType(keyInfo.Type))
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -200,8 +194,8 @@ func (ms *MessageSigner) dstoreKey(addr address.Address) datastore.Key {
return datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()}) return datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()})
} }
func SigningBytes(msg *types.Message, sigType crypto.SigType) ([]byte, error) { func SigningBytes(msg *types.Message, sigType address.Protocol) ([]byte, error) {
if sigType == crypto.SigTypeDelegated { if sigType == address.Delegated {
txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msg) txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(msg)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to reconstruct eth transaction: %w", err) return nil, xerrors.Errorf("failed to reconstruct eth transaction: %w", err)

View File

@ -44,12 +44,12 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.
msg.Value = types.NewInt(0) 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. // 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) { 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. // 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 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 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 // - If executing a message at a given tipset or its parent would trigger an expensive migration, the call will
// fail with ErrExpensiveFork. // 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") ctx, span := trace.StartSpan(ctx, "statemanager.callInternal")
defer span.End() defer span.End()
@ -107,22 +107,18 @@ func (sm *StateManager) callInternal(ctx context.Context, msg *types.Message, pr
} }
} }
var vmHeight abi.ChainEpoch // Unless executing on a specific state cid, apply all the messages from the current tipset
if checkGas { // first. Unfortunately, we can't just execute the tipset, because that will run cron. We
// Since we're simulating a future message, pretend we're applying it in the "next" tipset // don't want to apply miner messages after cron runs in a given epoch.
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 { if stateCid == cid.Undef {
stateCid = ts.ParentState() 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. // 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()) buffStore := blockstore.NewTieredBstore(sm.cs.StateBlockstore(), blockstore.NewMemorySync())
vmopt := &vm.VMOpts{ vmopt := &vm.VMOpts{
StateBase: stateCid, StateBase: stateCid,
Epoch: vmHeight, Epoch: ts.Height(),
Timestamp: ts.MinTimestamp(), Timestamp: ts.MinTimestamp(),
Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, nvGetter), Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, nvGetter),
Bstore: buffStore, Bstore: buffStore,
Actors: sm.tsExec.NewActorRegistry(), Actors: sm.tsExec.NewActorRegistry(),
Syscalls: sm.Syscalls, Syscalls: sm.Syscalls,
CircSupplyCalc: sm.GetVMCirculatingSupply, CircSupplyCalc: sm.GetVMCirculatingSupply,
NetworkVersion: nvGetter(ctx, vmHeight), NetworkVersion: nvGetter(ctx, ts.Height()),
BaseFee: ts.Blocks()[0].ParentBaseFee, BaseFee: ts.Blocks()[0].ParentBaseFee,
LookbackState: LookbackStateGetterForTipset(sm, ts), LookbackState: LookbackStateGetterForTipset(sm, ts),
TipSetGetter: TipSetGetterForTipset(sm.cs, ts), TipSetGetter: TipSetGetterForTipset(sm.cs, ts),

View File

@ -256,6 +256,20 @@ func (cs *ChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader
return blsmsgs, secpkmsgs, nil 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) { func (cs *ChainStore) GetParentReceipt(ctx context.Context, b *types.BlockHeader, i int) (*types.MessageReceipt, error) {
// block headers use adt0, for now. // block headers use adt0, for now.
a, err := blockadt.AsArray(cs.ActorStore(ctx), b.ParentMessageReceipts) a, err := blockadt.AsArray(cs.ActorStore(ctx), b.ParentMessageReceipts)

View File

@ -1943,7 +1943,7 @@ func (t *Event) UnmarshalCBOR(r io.Reader) (err error) {
return nil return nil
} }
var lengthBufEventEntry = []byte{131} var lengthBufEventEntry = []byte{132}
func (t *EventEntry) MarshalCBOR(w io.Writer) error { func (t *EventEntry) MarshalCBOR(w io.Writer) error {
if t == nil { if t == nil {
@ -1974,6 +1974,12 @@ func (t *EventEntry) MarshalCBOR(w io.Writer) error {
return err return err
} }
// t.Codec (uint64) (uint64)
if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Codec)); err != nil {
return err
}
// t.Value ([]uint8) (slice) // t.Value ([]uint8) (slice)
if len(t.Value) > cbg.ByteArrayMaxLen { if len(t.Value) > cbg.ByteArrayMaxLen {
return xerrors.Errorf("Byte array in field t.Value was too long") 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") 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") 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.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) // t.Value ([]uint8) (slice)
maj, extra, err = cr.ReadHeader() maj, extra, err = cr.ReadHeader()

View File

@ -37,7 +37,8 @@ type EthTx struct {
Gas EthUint64 `json:"gas"` Gas EthUint64 `json:"gas"`
MaxFeePerGas EthBigInt `json:"maxFeePerGas"` MaxFeePerGas EthBigInt `json:"maxFeePerGas"`
MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"` MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"`
V EthBigInt `json:"v"` AccessList []EthHash `json:"accessList"`
V EthBigInt `json:"yParity"`
R EthBigInt `json:"r"` R EthBigInt `json:"r"`
S EthBigInt `json:"s"` S EthBigInt `json:"s"`
} }
@ -86,6 +87,7 @@ func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) {
Gas: EthUint64(txArgs.GasLimit), Gas: EthUint64(txArgs.GasLimit),
MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas), MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas),
MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas), MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas),
AccessList: []EthHash{},
V: v, V: v,
R: r, R: r,
S: s, S: s,

View File

@ -25,13 +25,6 @@ import (
"github.com/filecoin-project/lotus/lib/must" "github.com/filecoin-project/lotus/lib/must"
) )
var (
EthTopic1 = "t1"
EthTopic2 = "t2"
EthTopic3 = "t3"
EthTopic4 = "t4"
)
var ErrInvalidAddress = errors.New("invalid Filecoin Eth address") var ErrInvalidAddress = errors.New("invalid Filecoin Eth address")
type EthUint64 uint64 type EthUint64 uint64
@ -155,8 +148,11 @@ type EthBlock struct {
Uncles []EthHash `json:"uncles"` Uncles []EthHash `json:"uncles"`
} }
const EthBloomSize = 2048
var ( var (
EmptyEthBloom = [256]byte{} EmptyEthBloom = [EthBloomSize / 8]byte{}
FullEthBloom = [EthBloomSize / 8]byte{}
EmptyEthHash = EthHash{} EmptyEthHash = EthHash{}
EmptyUncleHash = must.One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array 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 EmptyRootHash = must.One(ParseEthHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) // Keccak-256 hash of the RLP of null
@ -164,6 +160,12 @@ var (
EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} 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 { func NewEthBlock(hasTransactions bool) EthBlock {
b := EthBlock{ b := EthBlock{
Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles. Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles.
@ -171,7 +173,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. TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions.
ReceiptsRoot: EmptyEthHash, ReceiptsRoot: EmptyEthHash,
Difficulty: EmptyEthInt, Difficulty: EmptyEthInt,
LogsBloom: EmptyEthBloom[:], LogsBloom: FullEthBloom[:],
Extradata: []byte{}, Extradata: []byte{},
MixHash: EmptyEthHash, MixHash: EmptyEthHash,
Nonce: EmptyEthNonce, Nonce: EmptyEthNonce,
@ -404,6 +406,10 @@ func DecodeHexString(s string) ([]byte, error) {
return b, nil return b, nil
} }
func DecodeHexStringTrimSpace(s string) ([]byte, error) {
return DecodeHexString(strings.TrimSpace(s))
}
func handleHexStringPrefix(s string) string { func handleHexStringPrefix(s string) string {
// Strip the leading 0x or 0X prefix since hex.DecodeString does not support it. // Strip the leading 0x or 0X prefix since hex.DecodeString does not support it.
if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") {
@ -440,6 +446,17 @@ func EthHashFromTxBytes(b []byte) EthHash {
return 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 { type EthFeeHistory struct {
OldestBlock EthUint64 `json:"oldestBlock"` OldestBlock EthUint64 `json:"oldestBlock"`
BaseFeePerGas []EthBigInt `json:"baseFeePerGas"` BaseFeePerGas []EthBigInt `json:"baseFeePerGas"`
@ -602,7 +619,7 @@ type EthLog struct {
Data EthBytes `json:"data"` Data EthBytes `json:"data"`
// List of topics associated with the event log. // 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 // Following fields are derived from the transaction containing the log

View File

@ -216,7 +216,7 @@ func TestEthFilterResultMarshalJSON(t *testing.T) {
TransactionHash: hash1, TransactionHash: hash1,
BlockHash: hash2, BlockHash: hash2,
BlockNumber: 53, BlockNumber: 53,
Topics: []EthBytes{hash1[:]}, Topics: []EthHash{hash1},
Data: EthBytes(hash1[:]), Data: EthBytes(hash1[:]),
Address: addr, Address: addr,
} }

View File

@ -30,7 +30,10 @@ type EventEntry struct {
// The key of this event entry // The key of this event entry
Key string Key string
// Any DAG-CBOR encodeable type. // The event value's codec
Codec uint64
// The event value
Value []byte Value []byte
} }

View File

@ -213,6 +213,16 @@ var Prices = map[abi.ChainEpoch]Pricelist{
verifyReplicaUpdate: 36316136, 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 // PricelistByEpoch finds the latest prices for the given epoch

View File

@ -291,7 +291,7 @@ func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{},
um := actInfo.vmActor.State() um := actInfo.vmActor.State()
if um == nil { 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) 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)
} }

View File

@ -107,7 +107,7 @@ var EvmCallSimulateCmd = &cli.Command{
return err return err
} }
params, err := ethtypes.DecodeHexString(cctx.Args().Get(2)) params, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(2))
if err != nil { if err != nil {
return err return err
} }
@ -151,7 +151,7 @@ var EvmGetContractAddress = &cli.Command{
return err return err
} }
salt, err := ethtypes.DecodeHexString(cctx.Args().Get(1)) salt, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1))
if err != nil { if err != nil {
return xerrors.Errorf("Could not decode salt: %w", err) return xerrors.Errorf("Could not decode salt: %w", err)
} }
@ -170,7 +170,7 @@ var EvmGetContractAddress = &cli.Command{
return err return err
} }
contract, err := ethtypes.DecodeHexString(string(contractHex)) contract, err := ethtypes.DecodeHexStringTrimSpace(string(contractHex))
if err != nil { if err != nil {
return xerrors.Errorf("Could not decode contract file: %w", err) 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) return xerrors.Errorf("failed to read contract: %w", err)
} }
if cctx.Bool("hex") { if cctx.Bool("hex") {
contract, err = ethtypes.DecodeHexString(string(contract)) contract, err = ethtypes.DecodeHexStringTrimSpace(string(contract))
if err != nil { if err != nil {
return xerrors.Errorf("failed to decode contract: %w", err) return xerrors.Errorf("failed to decode contract: %w", err)
} }
@ -341,7 +341,7 @@ var EvmInvokeCmd = &cli.Command{
} }
var calldata []byte var calldata []byte
calldata, err = ethtypes.DecodeHexString(cctx.Args().Get(1)) calldata, err = ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1))
if err != nil { if err != nil {
return xerrors.Errorf("decoding hex input data: %w", err) return xerrors.Errorf("decoding hex input data: %w", err)
} }

View File

@ -117,6 +117,17 @@ var sendCmd = &cli.Command{
params.From = faddr 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") { if cctx.IsSet("gas-premium") {
gp, err := types.BigFromString(cctx.String("gas-premium")) gp, err := types.BigFromString(cctx.String("gas-premium"))
if err != nil { if err != nil {

View File

@ -457,6 +457,7 @@ var chainBalanceStateCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "miner-info", Name: "miner-info",
@ -680,6 +681,7 @@ var chainPledgeCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
ArgsUsage: "[stateroot epoch]", ArgsUsage: "[stateroot epoch]",

View File

@ -41,6 +41,11 @@ var datastoreListCmd = &cli.Command{
Name: "list", Name: "list",
Description: "list datastore keys", Description: "list datastore keys",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
},
&cli.StringFlag{ &cli.StringFlag{
Name: "repo-type", Name: "repo-type",
Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)",
@ -110,6 +115,11 @@ var datastoreGetCmd = &cli.Command{
Name: "get", Name: "get",
Description: "list datastore keys", Description: "list datastore keys",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
},
&cli.StringFlag{ &cli.StringFlag{
Name: "repo-type", Name: "repo-type",
Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)",
@ -123,7 +133,7 @@ var datastoreGetCmd = &cli.Command{
}, },
ArgsUsage: "[namespace key]", ArgsUsage: "[namespace key]",
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
logging.SetLogLevel("badger", "ERROR") // nolint:errcheck _ = logging.SetLogLevel("badger", "ERROR")
r, err := repo.NewFS(cctx.String("repo")) r, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {

View File

@ -26,6 +26,7 @@ var dealLabelCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -35,6 +35,7 @@ var diffMinerStates = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -37,6 +37,7 @@ var exportCarCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
ArgsUsage: "[outfile] [root cid]", ArgsUsage: "[outfile] [root cid]",

View File

@ -44,6 +44,7 @@ var exportChainCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "tipset", Name: "tipset",
@ -148,6 +149,7 @@ var exportRawCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "car-size", Name: "car-size",

View File

@ -58,12 +58,6 @@ var fip36PollCmd = &cli.Command{
Name: "fip36poll", Name: "fip36poll",
Usage: "Process the FIP0036 FilPoll result", Usage: "Process the FIP0036 FilPoll result",
ArgsUsage: "[state root, votes]", ArgsUsage: "[state root, votes]",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
Value: "~/.lotus",
},
},
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
finalResultCmd, finalResultCmd,
}, },
@ -77,6 +71,7 @@ var finalResultCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },

View File

@ -45,6 +45,7 @@ var gasTraceCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
@ -149,6 +150,7 @@ var replayOfflineCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.Int64Flag{ &cli.Int64Flag{
Name: "lookback-limit", Name: "lookback-limit",

View File

@ -19,6 +19,13 @@ import (
var importCarCmd = &cli.Command{ var importCarCmd = &cli.Command{
Name: "import-car", Name: "import-car",
Description: "Import a car file into node chain blockstore", 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 { Action: func(cctx *cli.Context) error {
r, err := repo.NewFS(cctx.String("repo")) r, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {
@ -96,6 +103,13 @@ var importCarCmd = &cli.Command{
var importObjectCmd = &cli.Command{ var importObjectCmd = &cli.Command{
Name: "import-obj", Name: "import-obj",
Usage: "import a raw ipld object into your datastore", 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 { Action: func(cctx *cli.Context) error {
r, err := repo.NewFS(cctx.String("repo")) r, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {

View File

@ -38,6 +38,7 @@ var invariantsCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -146,9 +146,14 @@ var keyinfoImportCmd = &cli.Command{
Examples Examples
env LOTUS_PATH=/var/lib/lotus lotus-shed keyinfo import libp2p-host.keyinfo`, 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 { Action: func(cctx *cli.Context) error {
flagRepo := cctx.String("repo")
var input io.Reader var input io.Reader
if cctx.NArg() == 0 { if cctx.NArg() == 0 {
input = os.Stdin input = os.Stdin
@ -177,7 +182,7 @@ var keyinfoImportCmd = &cli.Command{
return err return err
} }
fsrepo, err := repo.NewFS(flagRepo) fsrepo, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {
return err return err
} }

View File

@ -1,7 +1,6 @@
package main package main
import ( import (
"fmt"
"os" "os"
logging "github.com/ipfs/go-log/v2" logging "github.com/ipfs/go-log/v2"
@ -91,19 +90,6 @@ func main() {
Version: build.UserVersion(), Version: build.UserVersion(),
Commands: local, Commands: local,
Flags: []cli.Flag{ 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{ &cli.StringFlag{
Name: "log-level", Name: "log-level",
Value: "info", Value: "info",

View File

@ -125,7 +125,8 @@ var marketExportDatastoreCmd = &cli.Command{
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Usage: "path to the repo", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "backup-dir", Name: "backup-dir",
@ -242,7 +243,8 @@ var marketImportDatastoreCmd = &cli.Command{
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Usage: "path to the repo", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "backup-path", Name: "backup-path",

View File

@ -57,6 +57,7 @@ var migrationsCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "skip-pre-migration", Name: "skip-pre-migration",

View File

@ -26,10 +26,12 @@ import (
var minerPeeridCmd = &cli.Command{ var minerPeeridCmd = &cli.Command{
Name: "miner-peerid", 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{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -28,10 +28,12 @@ import (
var minerTypesCmd = &cli.Command{ var minerTypesCmd = &cli.Command{
Name: "miner-types", 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{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -45,6 +45,7 @@ var multisigGetAllCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -17,12 +17,6 @@ import (
var noncefix = &cli.Command{ var noncefix = &cli.Command{
Name: "noncefix", Name: "noncefix",
Flags: []cli.Flag{ Flags: []cli.Flag{
&cli.StringFlag{
Name: "repo",
EnvVars: []string{"LOTUS_PATH"},
Hidden: true,
Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME
},
&cli.Uint64Flag{ &cli.Uint64Flag{
Name: "start", Name: "start",
}, },

View File

@ -88,6 +88,7 @@ var stateTreePruneCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.Int64Flag{ &cli.Int64Flag{
Name: "keep-from-lookback", Name: "keep-from-lookback",

View File

@ -41,6 +41,7 @@ var splitstoreRollbackCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "gc-coldstore", Name: "gc-coldstore",
@ -131,6 +132,7 @@ var splitstoreClearCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "keys-only", Name: "keys-only",

View File

@ -35,6 +35,7 @@ var terminationsCmd = &cli.Command{
&cli.StringFlag{ &cli.StringFlag{
Name: "repo", Name: "repo",
Value: "~/.lotus", Value: "~/.lotus",
EnvVars: []string{"LOTUS_PATH"},
}, },
}, },
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {

View File

@ -644,6 +644,7 @@ Response:
{ {
"Flags": 7, "Flags": 7,
"Key": "string value", "Key": "string value",
"Codec": 42,
"Value": "Ynl0ZSBhcnJheQ==" "Value": "Ynl0ZSBhcnJheQ=="
} }
] ]
@ -2643,7 +2644,10 @@ Response:
"gas": "0x5", "gas": "0x5",
"maxFeePerGas": "0x0", "maxFeePerGas": "0x0",
"maxPriorityFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0",
"v": "0x0", "accessList": [
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
],
"yParity": "0x0",
"r": "0x0", "r": "0x0",
"s": "0x0" "s": "0x0"
} }
@ -2679,7 +2683,10 @@ Response:
"gas": "0x5", "gas": "0x5",
"maxFeePerGas": "0x0", "maxFeePerGas": "0x0",
"maxPriorityFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0",
"v": "0x0", "accessList": [
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
],
"yParity": "0x0",
"r": "0x0", "r": "0x0",
"s": "0x0" "s": "0x0"
} }
@ -2714,7 +2721,10 @@ Response:
"gas": "0x5", "gas": "0x5",
"maxFeePerGas": "0x0", "maxFeePerGas": "0x0",
"maxPriorityFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0",
"v": "0x0", "accessList": [
"0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
],
"yParity": "0x0",
"r": "0x0", "r": "0x0",
"s": "0x0" "s": "0x0"
} }
@ -2784,7 +2794,7 @@ Response:
"address": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031", "address": "0x5cbeecf99d3fdb3f25e309cc264f240bb0664031",
"data": "0x07", "data": "0x07",
"topics": [ "topics": [
"0x07" "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e"
], ],
"removed": true, "removed": true,
"logIndex": "0x5", "logIndex": "0x5",

2
extern/filecoin-ffi vendored

@ -1 +1 @@
Subproject commit 0c792ee1d1f062377033d7d37442d18f765be467 Subproject commit 4c503e5e2291b5d541f89d982d975e7994536a54

2
extern/test-vectors vendored

@ -1 +1 @@
Subproject commit d9a75a7873aee0db28b87e3970d2ea16a2f37c6a Subproject commit 28b0c45eab4c302864af0aeaaff813625cfafe97

View File

@ -20,6 +20,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet
{{- range . }} { {{- range . }} {
Network: {{printf "%q" .Network}}, Network: {{printf "%q" .Network}},
Version: {{.Version}}, Version: {{.Version}},
{{if .BundleGitTag}} BundleGitTag: {{printf "%q" .BundleGitTag}}, {{end}}
ManifestCid: MustParseCid({{printf "%q" .ManifestCid}}), ManifestCid: MustParseCid({{printf "%q" .ManifestCid}}),
Actors: map[string]cid.Cid { Actors: map[string]cid.Cid {
{{- range $name, $cid := .Actors }} {{- range $name, $cid := .Actors }}
@ -37,6 +38,14 @@ func main() {
panic(err) 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") fi, err := os.Create("./build/builtin_actors_gen.go")
if err != nil { if err != nil {
panic(err) panic(err)

2
go.mod
View File

@ -44,7 +44,7 @@ require (
github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-legs v0.4.4
github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-padreader v0.0.1
github.com/filecoin-project/go-paramfetch v0.0.4 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-statemachine v1.0.2
github.com/filecoin-project/go-statestore v0.2.0 github.com/filecoin-project/go-statestore v0.2.0
github.com/filecoin-project/go-storedcounter v0.1.0 github.com/filecoin-project/go-storedcounter v0.1.0

4
go.sum
View File

@ -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.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.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.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-rc2 h1:nl92h86XridAoy0fjvW+8/8/eI0caVSm0fhAnIvtR64=
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/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 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 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc=
github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54=

File diff suppressed because one or more lines are too long

View File

@ -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));
}
}

View File

@ -0,0 +1 @@
60806040523460405161001190610073565b6040518091039082f090508015801561002e573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061007f565b60c78061031683390190565b6102888061008e6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630e3608df146100465780634313b53114610064578063b0d22c6214610082575b600080fd5b61004e6100a0565b60405161005b919061017d565b60405180910390f35b61006c610137565b60405161007991906101d9565b60405180910390f35b61008a61015b565b604051610097919061017d565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166312065fe06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101329190610225565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006007905090565b6000819050919050565b61017781610164565b82525050565b6000602082019050610192600083018461016e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c382610198565b9050919050565b6101d3816101b8565b82525050565b60006020820190506101ee60008301846101ca565b92915050565b600080fd5b61020281610164565b811461020d57600080fd5b50565b60008151905061021f816101f9565b92915050565b60006020828403121561023b5761023a6101f4565b5b600061024984828501610210565b9150509291505056fea2646970667358221220c24abd10dbe58d92bfe62cb351771fcdc45d54241a8ce7085f2a75179c67cd8a64736f6c63430008110033608060405260b5806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806312065fe014602d575b600080fd5b60336047565b604051603e91906066565b60405180910390f35b600047905090565b6000819050919050565b606081604f565b82525050565b6000602082019050607960008301846059565b9291505056fea26469706673582212207123972a300833ee01aebf99e4bdf8ecf9f01c0d3dd776048bd41803c6855c0e64736f6c63430008110033

View File

@ -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;
}
}

2
itests/contracts/compile.sh Executable file → Normal file
View File

@ -12,7 +12,7 @@ find . -name \*.sol -print0 |
#for these contracts we have 2 contracts in the same solidity file #for these contracts we have 2 contracts in the same solidity file
#this command grabs the correct bytecode for us #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 echo $filename
solc --bin $filename.sol | tail -n5|head -n1 | tr -d "\n" > $filename.hex solc --bin $filename.sol | tail -n5|head -n1 | tr -d "\n" > $filename.hex
done done

View File

@ -139,8 +139,6 @@ func TestEthOpenRPCConformance(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
defer closer() defer closer()
const skipUntilIssue10106 = "Skipped until EthTx is updated, see https://github.com/filecoin-project/lotus/issues/10106"
testCases := []struct { testCases := []struct {
method string method string
variant string // suffix applied to the test name to distinguish different variants of a method call variant string // suffix applied to the test name to distinguish different variants of a method call
@ -227,7 +225,6 @@ func TestEthOpenRPCConformance(t *testing.T) {
call: func(a *ethAPIRaw) (json.RawMessage, error) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetBlockByHash(context.Background(), blockHashWithMessage, true) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetBlockByNumber(context.Background(), "earliest", true) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetBlockByNumber(context.Background(), "pending", true) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetBlockByNumber(context.Background(), blockNumberWithMessage.Hex(), true) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetTransactionByBlockHashAndIndex(context.Background(), blockHashWithMessage, ethtypes.EthUint64(0)) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetTransactionByBlockNumberAndIndex(context.Background(), blockNumberWithMessage, ethtypes.EthUint64(0)) 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) { call: func(a *ethAPIRaw) (json.RawMessage, error) {
return ethapi.EthGetTransactionByHash(context.Background(), &messageWithEvents) return ethapi.EthGetTransactionByHash(context.Background(), &messageWithEvents)
}, },
skipReason: skipUntilIssue10106,
}, },
{ {

View File

@ -11,12 +11,16 @@ import (
"time" "time"
"github.com/stretchr/testify/require" "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/big"
"github.com/filecoin-project/go-state-types/manifest" "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/api"
"github.com/filecoin-project/lotus/blockstore"
"github.com/filecoin-project/lotus/build" "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"
"github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/itests/kit"
@ -219,4 +223,32 @@ func TestDeployment(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
client.AssertActorType(ctx, contractAddr, "evm") 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)
} }

View File

@ -7,6 +7,7 @@ import (
"encoding/hex" "encoding/hex"
"encoding/json" "encoding/json"
"fmt" "fmt"
"math/bits"
"os" "os"
"sort" "sort"
"strconv" "strconv"
@ -16,7 +17,6 @@ import (
"github.com/ipfs/go-cid" "github.com/ipfs/go-cid"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
cbg "github.com/whyrusleeping/cbor-gen"
"golang.org/x/xerrors" "golang.org/x/xerrors"
"github.com/filecoin-project/go-address" "github.com/filecoin-project/go-address"
@ -285,33 +285,33 @@ func TestEthNewFilterDefaultSpec(t *testing.T) {
expected := []ExpectedEthLog{ expected := []ExpectedEthLog{
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
paddedEthBytes([]byte{0x11, 0x11}), paddedEthHash([]byte{0x11, 0x11}),
paddedEthBytes([]byte{0x22, 0x22}), paddedEthHash([]byte{0x22, 0x22}),
paddedEthBytes([]byte{0x33, 0x33}), paddedEthHash([]byte{0x33, 0x33}),
paddedEthBytes([]byte{0x44, 0x44}), 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, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
paddedEthBytes([]byte{0x11, 0x11}), paddedEthHash([]byte{0x11, 0x11}),
paddedEthBytes([]byte{0x22, 0x22}), paddedEthHash([]byte{0x22, 0x22}),
paddedEthBytes([]byte{0x33, 0x33}), paddedEthHash([]byte{0x33, 0x33}),
paddedEthBytes([]byte{0x44, 0x44}), 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, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
paddedEthBytes([]byte{0x11, 0x11}), paddedEthHash([]byte{0x11, 0x11}),
paddedEthBytes([]byte{0x22, 0x22}), paddedEthHash([]byte{0x22, 0x22}),
paddedEthBytes([]byte{0x33, 0x33}), paddedEthHash([]byte{0x33, 0x33}),
paddedEthBytes([]byte{0x44, 0x44}), 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{ expected := []ExpectedEthLog{
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
paddedEthBytes([]byte{0x11, 0x11}), paddedEthHash([]byte{0x11, 0x11}),
paddedEthBytes([]byte{0x22, 0x22}), paddedEthHash([]byte{0x22, 0x22}),
paddedEthBytes([]byte{0x33, 0x33}), paddedEthHash([]byte{0x33, 0x33}),
paddedEthBytes([]byte{0x44, 0x44}), 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 { for i := range expected {
expected[i] = ExpectedEthLog{ expected[i] = ExpectedEthLog{
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
paddedEthBytes([]byte{0x11, 0x11}), paddedEthHash([]byte{0x11, 0x11}),
paddedEthBytes([]byte{0x22, 0x22}), paddedEthHash([]byte{0x22, 0x22}),
paddedEthBytes([]byte{0x33, 0x33}), paddedEthHash([]byte{0x33, 0x33}),
paddedEthBytes([]byte{0x44, 0x44}), 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) 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) { func TestEthGetLogs(t *testing.T) {
require := require.New(t) require := require.New(t)
kit.QuietAllLogsExcept("events", "messagepool") kit.QuietAllLogsExcept("events", "messagepool")
@ -563,11 +608,7 @@ func TestEthSubscribeLogs(t *testing.T) {
var elogs []*ethtypes.EthLog var elogs []*ethtypes.EthLog
for resp := range responseCh { for resp := range responseCh {
rlist, ok := resp.Result.([]interface{}) rmap, ok := resp.Result.(map[string]interface{})
require.True(ok, "expected subscription result to be []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) require.True(ok, "expected subscription result entry to be map[string]interface{}, but was %T", resp.Result)
elog, err := ParseEthLog(rmap) elog, err := ParseEthLog(rmap)
@ -575,8 +616,6 @@ func TestEthSubscribeLogs(t *testing.T) {
elogs = append(elogs, elog) elogs = append(elogs, elog)
} }
}
AssertEthLogs(t, elogs, tc.expected, messages) AssertEthLogs(t, elogs, tc.expected, messages)
}) })
} }
@ -657,10 +696,10 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) {
distinctHeights[m.ts.Height()] = true distinctHeights[m.ts.Height()] = true
expectedByHeight[m.ts.Height()] = append(expectedByHeight[m.ts.Height()], ExpectedEthLog{ expectedByHeight[m.ts.Height()] = append(expectedByHeight[m.ts.Height()], ExpectedEthLog{
Address: addr, Address: addr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(args[0]), uint64EthHash(args[0]),
paddedUint64(args[1]), uint64EthHash(args[1]),
}, },
Data: paddedUint64(args[2]), Data: paddedUint64(args[2]),
}) })
@ -723,7 +762,7 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) {
require.True(len(partition3.expected) > 0, "partition should have events") require.True(len(partition3.expected) > 0, "partition should have events")
// these are the topics we selected for partitioning earlier // 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 { union := func(lists ...[]ExpectedEthLog) []ExpectedEthLog {
ret := []ExpectedEthLog{} ret := []ExpectedEthLog{}
@ -911,30 +950,30 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) {
expected := []ExpectedEthLog{ expected := []ExpectedEthLog{
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneData"], kit.EventMatrixContract.Ev["EventOneData"],
}, },
Data: paddedUint64(1), Data: paddedUint64(1),
}, },
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexed"], kit.EventMatrixContract.Ev["EventOneIndexed"],
paddedUint64(2), uint64EthHash(2),
}, },
}, },
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneData"], kit.EventMatrixContract.Ev["EventOneData"],
}, },
Data: paddedUint64(3), Data: paddedUint64(3),
}, },
{ {
Address: ethContractAddr, Address: ethContractAddr,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexed"], kit.EventMatrixContract.Ev["EventOneIndexed"],
paddedUint64(4), uint64EthHash(4),
}, },
}, },
} }
@ -1325,19 +1364,19 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
return []filterTestCase{ return []filterTestCase{
{ {
name: "find all EventZeroData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventZeroData"], kit.EventMatrixContract.Ev["EventZeroData"],
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventZeroData"], kit.EventMatrixContract.Ev["EventZeroData"],
}, },
Data: nil, Data: nil,
@ -1346,19 +1385,19 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventOneData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneData"], kit.EventMatrixContract.Ev["EventOneData"],
}, },
Data: packUint64Values(23), Data: packUint64Values(23),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneData"], kit.EventMatrixContract.Ev["EventOneData"],
}, },
Data: packUint64Values(44), Data: packUint64Values(44),
@ -1367,12 +1406,12 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventTwoData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoData"], kit.EventMatrixContract.Ev["EventTwoData"],
}, },
Data: packUint64Values(555, 666), Data: packUint64Values(555, 666),
@ -1381,12 +1420,12 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventThreeData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeData"], kit.EventMatrixContract.Ev["EventThreeData"],
}, },
Data: packUint64Values(1, 2, 3), Data: packUint64Values(1, 2, 3),
@ -1395,14 +1434,14 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventOneIndexed events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexed"], kit.EventMatrixContract.Ev["EventOneIndexed"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: nil, Data: nil,
}, },
@ -1410,24 +1449,24 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventTwoIndexed events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexed"], kit.EventMatrixContract.Ev["EventTwoIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexed"], kit.EventMatrixContract.Ev["EventTwoIndexed"],
paddedUint64(40), uint64EthHash(40),
paddedUint64(20), uint64EthHash(20),
}, },
Data: nil, Data: nil,
}, },
@ -1435,16 +1474,16 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventThreeIndexed events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexed"], kit.EventMatrixContract.Ev["EventThreeIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
@ -1452,30 +1491,30 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventOneIndexedWithData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(50), uint64EthHash(50),
}, },
Data: paddedUint64(9), Data: paddedUint64(9),
}, },
@ -1483,33 +1522,33 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventTwoIndexedWithData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(14), uint64EthHash(14),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
@ -1517,16 +1556,16 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all EventThreeIndexedWithData events", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], kit.EventMatrixContract.Ev["EventThreeIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
@ -1535,60 +1574,60 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
{ {
name: "find all events with topic2 of 44", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexed"], kit.EventMatrixContract.Ev["EventOneIndexed"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexed"], kit.EventMatrixContract.Ev["EventTwoIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexed"], kit.EventMatrixContract.Ev["EventThreeIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], kit.EventMatrixContract.Ev["EventThreeIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
@ -1596,32 +1635,32 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all events with topic2 of 46", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(14), uint64EthHash(14),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
@ -1629,14 +1668,14 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all events with topic2 of 50", 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{ expected: []ExpectedEthLog{
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(50), uint64EthHash(50),
}, },
Data: paddedUint64(9), Data: paddedUint64(9),
}, },
@ -1644,40 +1683,40 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock
}, },
{ {
name: "find all events with topic2 of 46 or 50", 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{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(14), uint64EthHash(14),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(50), uint64EthHash(50),
}, },
Data: paddedUint64(9), 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", name: "find all events with topic1 of EventTwoIndexedWithData and topic3 of 27",
spec: kit.NewEthFilterBuilder(). spec: kit.NewEthFilterBuilder().
FromBlockEpoch(0). FromBlockEpoch(0).
Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])). Topic1OneOf(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]).
Topic3OneOf(paddedEthHash(paddedUint64(27))). Topic3OneOf(uint64EthHash(27)).
Filter(), Filter(),
expected: []ExpectedEthLog{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), 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", name: "find all events with topic1 of EventTwoIndexedWithData or EventOneIndexed and topic2 of 44",
spec: kit.NewEthFilterBuilder(). spec: kit.NewEthFilterBuilder().
FromBlockEpoch(0). FromBlockEpoch(0).
Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]), paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexed"])). Topic1OneOf((kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]), kit.EventMatrixContract.Ev["EventOneIndexed"]).
Topic2OneOf(paddedEthHash(paddedUint64(44))). Topic2OneOf(uint64EthHash(44)).
Filter(), Filter(),
expected: []ExpectedEthLog{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], kit.EventMatrixContract.Ev["EventTwoIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexed"], kit.EventMatrixContract.Ev["EventOneIndexed"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: nil, Data: nil,
}, },
@ -1755,35 +1794,35 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo
expected: []ExpectedEthLog{ expected: []ExpectedEthLog{
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventZeroData"], kit.EventMatrixContract.Ev["EventZeroData"],
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexed"], kit.EventMatrixContract.Ev["EventThreeIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexed"], kit.EventMatrixContract.Ev["EventTwoIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(50), uint64EthHash(50),
}, },
Data: paddedUint64(9), Data: paddedUint64(9),
}, },
@ -1797,20 +1836,20 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo
expected: []ExpectedEthLog{ expected: []ExpectedEthLog{
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventThreeIndexed"], kit.EventMatrixContract.Ev["EventThreeIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(27), uint64EthHash(27),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventTwoIndexed"], kit.EventMatrixContract.Ev["EventTwoIndexed"],
paddedUint64(44), uint64EthHash(44),
paddedUint64(19), uint64EthHash(19),
}, },
Data: nil, Data: nil,
}, },
@ -1822,31 +1861,31 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo
spec: kit.NewEthFilterBuilder(). spec: kit.NewEthFilterBuilder().
FromBlockEpoch(0). FromBlockEpoch(0).
AddressOneOf(contract1, contract2). AddressOneOf(contract1, contract2).
Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexedWithData"])). Topic1OneOf(kit.EventMatrixContract.Ev["EventOneIndexedWithData"]).
Filter(), Filter(),
expected: []ExpectedEthLog{ expected: []ExpectedEthLog{
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(44), uint64EthHash(44),
}, },
Data: paddedUint64(19), Data: paddedUint64(19),
}, },
{ {
Address: contract1, Address: contract1,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(46), uint64EthHash(46),
}, },
Data: paddedUint64(12), Data: paddedUint64(12),
}, },
{ {
Address: contract2, Address: contract2,
Topics: []ethtypes.EthBytes{ Topics: []ethtypes.EthHash{
kit.EventMatrixContract.Ev["EventOneIndexedWithData"], kit.EventMatrixContract.Ev["EventOneIndexedWithData"],
paddedUint64(50), uint64EthHash(50),
}, },
Data: paddedUint64(9), Data: paddedUint64(9),
}, },
@ -1867,21 +1906,22 @@ type ExpectedEthLog struct {
Address ethtypes.EthAddress `json:"address"` Address ethtypes.EthAddress `json:"address"`
// List of topics associated with the event log. // 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 is the value of the event log, excluding topics
Data ethtypes.EthBytes `json:"data"` Data ethtypes.EthBytes `json:"data"`
} }
func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedEthLog, messages map[ethtypes.EthHash]msgInTipset) { func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedEthLog, messages map[ethtypes.EthHash]msgInTipset) {
t.Helper()
require := require.New(t) require := require.New(t)
t.Logf("got %d ethlogs, wanted %d", len(actual), len(expected)) 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)) ss := make([]string, len(topics))
for i := range 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, ",") return strings.Join(ss, ",")
} }
@ -1918,7 +1958,7 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE
} }
for j := range elog.Topics { for j := range elog.Topics {
if !bytes.Equal(elog.Topics[j], want.Topics[j]) { if elog.Topics[j] != want.Topics[j] {
continue LoopExpected 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("event %d\n", i))
buf.WriteString(fmt.Sprintf(" emitter: %v\n", ev.Emitter)) buf.WriteString(fmt.Sprintf(" emitter: %v\n", ev.Emitter))
for _, en := range ev.Entries { 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,15 +2006,9 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE
func parseEthLogsFromSubscriptionResponses(subResponses []ethtypes.EthSubscriptionResponse) ([]*ethtypes.EthLog, error) { func parseEthLogsFromSubscriptionResponses(subResponses []ethtypes.EthSubscriptionResponse) ([]*ethtypes.EthLog, error) {
elogs := make([]*ethtypes.EthLog, 0, len(subResponses)) elogs := make([]*ethtypes.EthLog, 0, len(subResponses))
for i := range subResponses { for i := range subResponses {
rlist, ok := subResponses[i].Result.([]interface{}) rmap, ok := subResponses[i].Result.(map[string]interface{})
if !ok { 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) elog, err := ParseEthLog(rmap)
@ -1983,7 +2017,6 @@ func parseEthLogsFromSubscriptionResponses(subResponses []ethtypes.EthSubscripti
} }
elogs = append(elogs, elog) elogs = append(elogs, elog)
} }
}
return elogs, nil return elogs, nil
} }
@ -2099,7 +2132,7 @@ func ParseEthLog(in map[string]interface{}) (*ethtypes.EthLog, error) {
if err != nil { if err != nil {
return nil, xerrors.Errorf("%s: %w", k, err) return nil, xerrors.Errorf("%s: %w", k, err)
} }
el.Topics = append(el.Topics, topic) el.Topics = append(el.Topics, paddedEthHash(topic))
continue continue
} }
@ -2112,7 +2145,7 @@ func ParseEthLog(in map[string]interface{}) (*ethtypes.EthLog, error) {
if err != nil { if err != nil {
return nil, xerrors.Errorf("%s: %w", k, err) 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 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 { func paddedUint64(v uint64) ethtypes.EthBytes {
buf := make([]byte, 32) buf := make([]byte, 32)
binary.BigEndian.PutUint64(buf[24:], v) binary.BigEndian.PutUint64(buf[24:], v)
return buf 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 { func paddedEthHash(orig []byte) ethtypes.EthHash {
if len(orig) > 32 { if len(orig) > 32 {
panic("exceeds EthHash length") panic("exceeds EthHash length")
@ -2167,14 +2196,3 @@ func unpackUint64Values(data []byte) []uint64 {
} }
return vals 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
}

View File

@ -3,6 +3,7 @@ package itests
import ( import (
"bytes" "bytes"
"context" "context"
"crypto/rand"
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"fmt" "fmt"
@ -57,7 +58,7 @@ func buildInputFromuint64(number uint64) []byte {
// recursive delegate calls that fail due to gas limits are currently getting to 229 iterations // recursive delegate calls that fail due to gas limits are currently getting to 229 iterations
// before running out of gas // before running out of gas
func recursiveDelegatecallFail(ctx context.Context, t *testing.T, client *kit.TestFullNode, filename string, count uint64) { 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) fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, filename)
t.Log("recursion count - ", count) t.Log("recursion count - ", count)
inputData := buildInputFromuint64(count) inputData := buildInputFromuint64(count)
@ -157,7 +158,7 @@ func TestFEVMRecursiveDelegatecallCount(t *testing.T) {
ctx, cancel, client := kit.SetupFEVMTest(t) ctx, cancel, client := kit.SetupFEVMTest(t)
defer cancel() defer cancel()
highestSuccessCount := uint64(237) highestSuccessCount := uint64(225)
filename := "contracts/RecursiveDelegeatecall.hex" filename := "contracts/RecursiveDelegeatecall.hex"
recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(1)) recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(1))
@ -601,10 +602,10 @@ func TestFEVMRecursiveActorCall(t *testing.T) {
t.Run("n=200,r=32", testN(200, 32, exitcode.Ok)) 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=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=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))) t.Run("n=251,r=167-fails", testN(251, 167, exitcode.ExitCode(33)))
} }
@ -704,3 +705,84 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) {
t.Run("n=50", testN(50)) t.Run("n=50", testN(50))
t.Run("n=100", testN(100)) 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)
}

View File

@ -2,16 +2,23 @@ package itests
import ( import (
"context" "context"
"math"
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/require" "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/big"
"github.com/filecoin-project/go-state-types/exitcode"
"github.com/filecoin-project/lotus/api" "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/actors/builtin/account"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/itests/kit" "github.com/filecoin-project/lotus/itests/kit"
) )
@ -37,8 +44,9 @@ func TestEstimateGasNoFunds(t *testing.T) {
sm, err := client.MpoolPushMessage(ctx, msg, nil) sm, err := client.MpoolPushMessage(ctx, msg, nil)
require.NoError(t, err) 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.NoError(t, err)
require.True(t, ret.Receipt.ExitCode.IsSuccess())
// Make sure we can estimate gas even if we have no funds. // Make sure we can estimate gas even if we have no funds.
msg2 := &types.Message{ msg2 := &types.Message{
@ -52,3 +60,110 @@ func TestEstimateGasNoFunds(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.NotZero(t, limit) 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")
}

View File

@ -43,19 +43,18 @@ func (f *TestFullNode) EVM() *EVM {
return &EVM{f} return &EVM{f}
} }
func (e *EVM) DeployContract(ctx context.Context, sender address.Address, bytecode []byte) eam.CreateReturn { func (e *EVM) DeployContractWithValue(ctx context.Context, sender address.Address, bytecode []byte, value big.Int) eam.CreateReturn {
var err error
require := require.New(e.t) require := require.New(e.t)
method := builtintypes.MethodsEAM.CreateExternal method := builtintypes.MethodsEAM.CreateExternal
initcode := abi.CborBytes(bytecode) initcode := abi.CborBytes(bytecode)
params, err := actors.SerializeParams(&initcode) params, errActors := actors.SerializeParams(&initcode)
require.NoError(err) require.NoError(errActors)
msg := &types.Message{ msg := &types.Message{
To: builtintypes.EthereumAddressManagerActorAddr, To: builtintypes.EthereumAddressManagerActorAddr,
From: sender, From: sender,
Value: big.Zero(), Value: value,
Method: method, Method: method,
Params: params, Params: params,
} }
@ -77,8 +76,11 @@ func (e *EVM) DeployContract(ctx context.Context, sender address.Address, byteco
return result 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) contractHex, err := os.ReadFile(binFilename)
require.NoError(e.t, err) require.NoError(e.t, err)
@ -91,12 +93,15 @@ func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string
fromAddr, err := e.WalletDefaultAddress(ctx) fromAddr, err := e.WalletDefaultAddress(ctx)
require.NoError(e.t, err) require.NoError(e.t, err)
result := e.DeployContract(ctx, fromAddr, contract) result := e.DeployContractWithValue(ctx, fromAddr, contract, value)
idAddr, err := address.NewIDAddress(result.ActorID) idAddr, err := address.NewIDAddress(result.ActorID)
require.NoError(e.t, err) require.NoError(e.t, err)
return fromAddr, idAddr 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) { func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target address.Address, selector []byte, inputData []byte) (*api.MsgLookup, error) {
params := append(selector, inputData...) params := append(selector, inputData...)

View File

@ -2,12 +2,16 @@ package kit
import ( import (
"golang.org/x/crypto/sha3" "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 := sha3.NewLegacyKeccak256()
hasher.Write([]byte(sig)) hasher.Write([]byte(sig))
return hasher.Sum(nil) var hash ethtypes.EthHash
copy(hash[:], hasher.Sum(nil))
return hash
} }
func EthFunctionHash(sig string) []byte { func EthFunctionHash(sig string) []byte {
@ -20,7 +24,7 @@ func EthFunctionHash(sig string) []byte {
type SolidityContractDef struct { type SolidityContractDef struct {
Filename string // filename of the hex of the contract, e.g. contracts/EventMatrix.hex 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 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 Ev map[string]ethtypes.EthHash // mapping of event names to 256-bit signature hashes
} }
var EventMatrixContract = SolidityContractDef{ var EventMatrixContract = SolidityContractDef{
@ -38,7 +42,7 @@ var EventMatrixContract = SolidityContractDef{
"logEventTwoIndexedWithData": EthFunctionHash("logEventTwoIndexedWithData(uint256,uint256,uint256)"), "logEventTwoIndexedWithData": EthFunctionHash("logEventTwoIndexedWithData(uint256,uint256,uint256)"),
"logEventThreeIndexedWithData": EthFunctionHash("logEventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), "logEventThreeIndexedWithData": EthFunctionHash("logEventThreeIndexedWithData(uint256,uint256,uint256,uint256)"),
}, },
Ev: map[string][]byte{ Ev: map[string]ethtypes.EthHash{
"EventZeroData": EthTopicHash("EventZeroData()"), "EventZeroData": EthTopicHash("EventZeroData()"),
"EventOneData": EthTopicHash("EventOneData(uint256)"), "EventOneData": EthTopicHash("EventOneData(uint256)"),
"EventTwoData": EthTopicHash("EventTwoData(uint256,uint256)"), "EventTwoData": EthTopicHash("EventTwoData(uint256,uint256)"),
@ -60,5 +64,5 @@ var EventsContract = SolidityContractDef{
"log_zero_nodata": {0x00, 0x00, 0x00, 0x01}, "log_zero_nodata": {0x00, 0x00, 0x00, 0x01},
"log_four_data": {0x00, 0x00, 0x00, 0x02}, "log_four_data": {0x00, 0x00, 0x00, 0x02},
}, },
Ev: map[string][]byte{}, Ev: map[string]ethtypes.EthHash{},
} }

View File

@ -113,7 +113,7 @@ func TestWindowPostDispute(t *testing.T) {
//stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001 //stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001
di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
require.NoError(t, err) 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 break
} }
build.Clock.Sleep(blocktime) build.Clock.Sleep(blocktime)
@ -217,7 +217,8 @@ func TestWindowPostDispute(t *testing.T) {
//stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001 //stm: @CHAIN_STATE_MINER_CALCULATE_DEADLINE_001
di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK) di, err = client.StateMinerProvingDeadline(ctx, evilMinerAddr, types.EmptyTSK)
require.NoError(t, err) require.NoError(t, err)
if di.Index == evilSectorLoc.Deadline {
if di.Index == evilSectorLoc.Deadline && di.CurrentEpoch-di.Open > 1 {
break break
} }
build.Clock.Sleep(blocktime) build.Clock.Sleep(blocktime)

View File

@ -12,7 +12,7 @@ import (
"github.com/filecoin-project/lotus/chain/types/ethtypes" "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{} type EthModuleDummy struct{}

View File

@ -1358,6 +1358,67 @@ type filterTipSetCollector interface {
TakeCollectedTipSets(context.Context) []types.TipSetKey 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) { func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*ethtypes.EthFilterResult, error) {
res := &ethtypes.EthFilterResult{} res := &ethtypes.EthFilterResult{}
for _, ev := range evs { for _, ev := range evs {
@ -1367,19 +1428,14 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht
TransactionIndex: ethtypes.EthUint64(ev.MsgIdx), TransactionIndex: ethtypes.EthUint64(ev.MsgIdx),
BlockNumber: ethtypes.EthUint64(ev.Height), BlockNumber: ethtypes.EthUint64(ev.Height),
} }
var (
err error
ok bool
)
var err error log.Data, log.Topics, ok = ethLogFromEvent(ev.Entries)
if !ok {
for _, entry := range ev.Entries { continue
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.Address, err = ethtypes.EthAddressFromFilecoinAddress(ev.EmitterAddr) log.Address, err = ethtypes.EthAddressFromFilecoinAddress(ev.EmitterAddr)
@ -1517,45 +1573,50 @@ func (e *ethSubscription) addFilter(ctx context.Context, f filter.Filter) {
e.filters = append(e.filters, f) 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) { func (e *ethSubscription) start(ctx context.Context) {
for { for {
select { select {
case <-ctx.Done(): case <-ctx.Done():
return return
case v := <-e.in: case v := <-e.in:
resp := ethtypes.EthSubscriptionResponse{
SubscriptionID: e.id,
}
var err error
switch vt := v.(type) { switch vt := v.(type) {
case *filter.CollectedEvent: 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: 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 { if err != nil {
break break
} }
resp.Result = eb e.send(ctx, ev)
default: default:
log.Warnf("unexpected subscription value type: %T", vt) 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 +1818,7 @@ func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, sa StateAPI
Gas: ethtypes.EthUint64(msg.GasLimit), Gas: ethtypes.EthUint64(msg.GasLimit),
MaxFeePerGas: ethtypes.EthBigInt(msg.GasFeeCap), MaxFeePerGas: ethtypes.EthBigInt(msg.GasFeeCap),
MaxPriorityFeePerGas: ethtypes.EthBigInt(msg.GasPremium), MaxPriorityFeePerGas: ethtypes.EthBigInt(msg.GasPremium),
AccessList: []ethtypes.EthHash{},
} }
} }
@ -1890,11 +1952,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
} }
if len(events) > 0 { 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)) receipt.Logs = make([]ethtypes.EthLog, 0, len(events))
for i, evt := range events { for i, evt := range events {
l := ethtypes.EthLog{ l := ethtypes.EthLog{
@ -1906,17 +1963,16 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
BlockNumber: blockNumber, BlockNumber: blockNumber,
} }
for _, entry := range evt.Entries { data, topics, ok := ethLogFromEvent(evt.Entries)
value, err := cborDecodeTopicValue(entry.Value) if !ok {
if err != nil { // not an eth event.
return api.EthTxReceipt{}, xerrors.Errorf("failed to decode event log value: %w", err) continue
}
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
} }
for _, topic := range topics {
ethtypes.EthBloomSet(receipt.LogsBloom, topic[:])
} }
l.Data = data
l.Topics = topics
addr, err := address.NewIDAddress(uint64(evt.Emitter)) addr, err := address.NewIDAddress(uint64(evt.Emitter))
if err != nil { if err != nil {
@ -1928,6 +1984,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook
return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err) return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err)
} }
ethtypes.EthBloomSet(receipt.LogsBloom, l.Address[:])
receipt.Logs = append(receipt.Logs, l) receipt.Logs = append(receipt.Logs, l)
} }
} }
@ -1971,6 +2028,52 @@ func (m *EthTxHashManager) Revert(ctx context.Context, from, to *types.TipSet) e
return nil 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) { func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager *EthTxHashManager) {
for { for {
select { select {
@ -1980,19 +2083,8 @@ func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager
if u.Type != api.MpoolAdd { if u.Type != api.MpoolAdd {
continue continue
} }
if u.Message.Signature.Type != crypto.SigTypeDelegated {
continue
}
ethTx, err := newEthTxFromSignedMessage(ctx, u.Message, manager.StateAPI) manager.ProcessSignedMessage(ctx, u.Message)
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)
}
} }
} }
} }
@ -2013,45 +2105,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) { func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) {
keys := map[string][][]byte{} keys := map[string][][]byte{}
for idx, vals := range topics { for idx, vals := range topics {
@ -2061,11 +2114,8 @@ func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) {
// Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4 // Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4
key := fmt.Sprintf("t%d", idx+1) key := fmt.Sprintf("t%d", idx+1)
for _, v := range vals { for _, v := range vals {
encodedVal, err := cborEncodeTopicValue(v[:]) v := v // copy the ethhash to avoid repeatedly referencing the same one.
if err != nil { keys[key] = append(keys[key], v[:])
return nil, xerrors.Errorf("failed to encode topic value")
}
keys[key] = append(keys[key], encodedVal)
} }
} }
return keys, nil return keys, nil

102
node/impl/full/eth_test.go Normal file
View File

@ -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{})
}

View File

@ -15,7 +15,6 @@ import (
"github.com/filecoin-project/lotus/chain/stmgr" "github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/wallet" "github.com/filecoin-project/lotus/chain/wallet"
"github.com/filecoin-project/lotus/chain/wallet/key"
"github.com/filecoin-project/lotus/lib/sigs" "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) return nil, xerrors.Errorf("failed to resolve ID address: %w", keyAddr)
} }
keyInfo, err := a.Wallet.WalletExport(ctx, k) sb, err := messagesigner.SigningBytes(msg, keyAddr.Protocol())
if err != nil {
return nil, err
}
sb, err := messagesigner.SigningBytes(msg, key.ActSigType(keyInfo.Type))
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,6 +2,7 @@ package modules
import ( import (
"context" "context"
"os"
"path/filepath" "path/filepath"
"go.uber.org/fx" "go.uber.org/fx"
@ -24,7 +25,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep
return nil, err 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 { if err != nil {
return nil, err return nil, err
} }
@ -40,6 +47,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep
TransactionHashLookup: transactionHashLookup, TransactionHashLookup: transactionHashLookup,
} }
if !dbAlreadyExists {
err = ethTxHashManager.PopulateExistingMappings(mctx, 0)
if err != nil {
return nil, err
}
}
const ChainHeadConfidence = 1 const ChainHeadConfidence = 1
ctx := helpers.LifecycleCtx(mctx, lc) ctx := helpers.LifecycleCtx(mctx, lc)