diff --git a/.circleci/config.yml b/.circleci/config.yml index 7d5cd2a25..88635ab2c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -603,6 +603,11 @@ workflows: suite: itest-deals target: "./itests/deals_test.go" + - test: + name: test-itest-decode_params + suite: itest-decode_params + target: "./itests/decode_params_test.go" + - test: name: test-itest-dup_mpool_messages suite: itest-dup_mpool_messages @@ -628,6 +633,11 @@ workflows: suite: itest-eth_config target: "./itests/eth_config_test.go" + - test: + name: test-itest-eth_conformance + suite: itest-eth_conformance + target: "./itests/eth_conformance_test.go" + - test: name: test-itest-eth_deploy suite: itest-eth_deploy diff --git a/Makefile b/Makefile index 43c362b86..023ca61f5 100644 --- a/Makefile +++ b/Makefile @@ -298,7 +298,7 @@ actors-gen: actors-code-gen fiximports .PHONY: actors-gen bundle-gen: - $(GOCC) run ./gen/bundle + $(GOCC) run ./gen/bundle $(RELEASE) $(GOCC) fmt ./build/... .PHONY: bundle-gen @@ -354,7 +354,7 @@ docsgen-openrpc-gateway: docsgen-openrpc-bin fiximports: ./scripts/fiximports -gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci bundle-gen fiximports +gen: actors-code-gen type-gen cfgdoc-gen docsgen api-gen circleci fiximports @echo ">>> IF YOU'VE MODIFIED THE CLI OR CONFIG, REMEMBER TO ALSO MAKE docsgen-cli" .PHONY: gen diff --git a/api/api_full.go b/api/api_full.go index 2ac92a764..20870adce 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -853,7 +853,7 @@ type FullNode interface { // reverse interface to the client, called after EthSubscribe type EthSubscriber interface { // note: the parameter is ethtypes.EthSubscriptionResponse serialized as json object - EthSubscription(ctx context.Context, r jsonrpc.RawParams) error //rpc_method:eth_subscription notify:true + EthSubscription(ctx context.Context, r jsonrpc.RawParams) error // rpc_method:eth_subscription notify:true } type StorageAsk struct { diff --git a/build/actors/pack.sh b/build/actors/pack.sh index c2060e67c..863a3c5c7 100755 --- a/build/actors/pack.sh +++ b/build/actors/pack.sh @@ -52,4 +52,4 @@ popd echo "Generating metadata..." -make -C ../../ bundle-gen +make -C ../../ RELEASE="$RELEASE" bundle-gen diff --git a/build/actors/v10.tar.zst b/build/actors/v10.tar.zst index d3a8e0a1e..70208151e 100644 Binary files a/build/actors/v10.tar.zst and b/build/actors/v10.tar.zst differ diff --git a/build/actors/v9.tar.zst b/build/actors/v9.tar.zst index 55d0eba0b..f19c7db4c 100644 Binary files a/build/actors/v9.tar.zst and b/build/actors/v9.tar.zst differ diff --git a/build/builtin_actors.go b/build/builtin_actors.go index 4d283919e..50aecde40 100644 --- a/build/builtin_actors.go +++ b/build/builtin_actors.go @@ -95,10 +95,11 @@ func loadManifests(netw string) error { } type BuiltinActorsMetadata struct { - Network string - Version actorstypes.Version - ManifestCid cid.Cid - Actors map[string]cid.Cid + Network string + Version actorstypes.Version + ManifestCid cid.Cid + Actors map[string]cid.Cid + BundleGitTag string } // ReadEmbeddedBuiltinActorsMetadata reads the metadata from the embedded built-in actor bundles. diff --git a/build/builtin_actors_gen.go b/build/builtin_actors_gen.go index 1f13ac6ed..df504f51d 100644 --- a/build/builtin_actors_gen.go +++ b/build/builtin_actors_gen.go @@ -31,46 +31,42 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "butterflynet", Version: 9, - ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), + ManifestCid: MustParseCid("bafy2bzacec35by4erhcdgcsgzp7yb3j57utydlxxfc73m3k5pep67ehvvyv6i"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), - "cron": MustParseCid("bafk2bzacecrszortqkc7har77ssgajglymv6ftrqvmdko5h2yqqh5k2qospl2"), - "datacap": MustParseCid("bafk2bzacecapjnxnyw4talwqv5ajbtbkzmzqiosztj5cb3sortyp73ndjl76e"), - "eam": MustParseCid("bafk2bzacecflry2dyjqj6fhpovkbcbei377zabectznuxsf6bxggsve7bsxga"), - "ethaccount": MustParseCid("bafk2bzacedl4pmkfxkzoqajs6im3ranmopozsmxjcxsnk3kwvd3vv7mfwwrf4"), - "evm": MustParseCid("bafk2bzacebgzvmvwv7rsnnhp3zhqbiqkumvyrc7pazfovpptgpgtqkalrli74"), - "init": MustParseCid("bafk2bzacecbxp66q3ytjkg37nyv4rmzezbfaigvx4i5yhvqbm5gg4amjeaias"), - "multisig": MustParseCid("bafk2bzacecjltag3mn75dsnmrmopjow27buxqhabissowayqlmavrcfetqswc"), - "paymentchannel": MustParseCid("bafk2bzacednzxg263eqbl2imwz3uhujov63tjkffieyl4hl3dhrgxyhwep6hc"), - "placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"), - "reward": MustParseCid("bafk2bzacectp23cxsbbdrr3uggnw7f263qll5wkkfzqhn5yq37ae2ehdjdzri"), - "storagemarket": MustParseCid("bafk2bzacea45ko3ezkpeujsniovncwnizc4wsxd7kyckskhs7gvzwthzb2mqe"), - "storageminer": MustParseCid("bafk2bzaced74qthwrl3gahcf7o3vrdrodbcqhlplh6fykbgy5sd2iyouhq44c"), - "storagepower": MustParseCid("bafk2bzaceduksv6wqthr5fgp7mx5prv6gzul2oozf3svrjbuggc4bgokdxgfy"), - "system": MustParseCid("bafk2bzacebe6j2ius6clbbr7dypsg54jzmn5xablzunph7ebedw6yhwla4cj2"), - "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), + "account": MustParseCid("bafk2bzaceajsdln7v4chxqoukiw7lxw6aexg5qdsaex2hgelz2sbu24iblhzg"), + "cron": MustParseCid("bafk2bzacecgrwmgnqhybn3l23uvwf2n2vrcfjrprfzgd44uxers2pgr5mhsue"), + "datacap": MustParseCid("bafk2bzacebyier2ceh27acbrq2ccv4efvzotl6qntnlrxdsrik6i4tembz6qw"), + "init": MustParseCid("bafk2bzaceberhto43wnf4pklkd4c7d36kzslngyzyms4op7shxuswv3dtvfxu"), + "multisig": MustParseCid("bafk2bzaceaclpbrhoqdruvsuqqgknvy2k5dywzmjoehk4uarce3uvt3w2rewu"), + "paymentchannel": MustParseCid("bafk2bzacedzp56g5cg73oilloak3kf7u667rdkd5pgnhe2cljmr3o7ykcrzuk"), + "reward": MustParseCid("bafk2bzacebczbwfbbi6mvppbjcozatasjiaohvjjiqcy65ccuuyyw3xiixhk2"), + "storagemarket": MustParseCid("bafk2bzaceawqexy6t2ybzh3jjwhbs7icbg5vqnedbbge4e4r4pfp7spkcadsu"), + "storageminer": MustParseCid("bafk2bzacearemd7pn2jj26fdtqd4di27lfhpng3vp5chepm7qnmdzgiqr6wfi"), + "storagepower": MustParseCid("bafk2bzaceddc7fiaxfobfegqaobf5xinjgmhsa5iu4yi6klvc3jmjimcdvgyg"), + "system": MustParseCid("bafk2bzacedylltr57b2n6zpadh4i2c2kis4fzzvhao3kgvfaggrrbqyacew7q"), + "verifiedregistry": MustParseCid("bafk2bzacecjkesz766626ab4svnzpq3jfs26a75vfktlfaku5fjdao2eyiqyq"), }, }, { Network: "butterflynet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacedsgi3wpyd46hbktrleolnlepzsm6k466fcrxuc7keht4guokgxiy"), + ManifestCid: MustParseCid("bafy2bzacecicijumaz6c5vpqwidz3kmfkn64wp76odwfo6ekvzjbx4gizrara"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebz7dm3vcuqtzzcf5jwvcubz6ecqk52t5rsd36fyzka2iosy4l4ro"), - "cron": MustParseCid("bafk2bzacea6qtj2wkbe2wq5vxc2knlnj3vdvk4bkjp36xtazgzhnegd2uaj7m"), - "datacap": MustParseCid("bafk2bzacedwxkx3jz7qwv5iwozadz7t5hhw5dtlgdxuwqxdp6oqguas7nakjk"), - "eam": MustParseCid("bafk2bzacedoegh4idwvhjqahfnbqq6aqzgccgjwumudx6ihfut36ng57or7fi"), - "ethaccount": MustParseCid("bafk2bzacebn6l3x7d2i6lv72osbgcl4a37imexh5ou5kvbmj56taetwcyyhgq"), - "evm": MustParseCid("bafk2bzaced5gaxg5mz3hho473aszx5brgjriicqgrcbqctnyyn2e6vcxv3ule"), - "init": MustParseCid("bafk2bzacecbo6ggprh7sz3oy6uu5raykwngqmnjdsiijdrgp4glet3mb65ywo"), - "multisig": MustParseCid("bafk2bzacecmu3bhbg4rh5sqbagjlvrpb6ip5k3pngq22a33ok44yuhk75zenq"), - "paymentchannel": MustParseCid("bafk2bzacebth7fqe5xts6hbm7m6n733qcu6b6atd7ur6l7jhddferjgpxdy4s"), + "account": MustParseCid("bafk2bzacedknkusm7lnhjpfe7djkxu6kwlqclsq7yk3s7h2wqtet2teul7hla"), + "cron": MustParseCid("bafk2bzacecvf4au52ks3btpfedsffhzkjvtogawsmpypjo4ddolszmszj62om"), + "datacap": MustParseCid("bafk2bzacecrgz4pzuonchcpbugavlmdrsakmz2qsjlpbt22yxum5r33tqkrls"), + "eam": MustParseCid("bafk2bzacecb4i45ifsj3kyeoglherbtc4dc37qrfa7meq37qtpio5gr6jcely"), + "ethaccount": MustParseCid("bafk2bzacec4l6ya2bate7r3yv7sutfhp4fmtcoxun36d4ltfdslczdgms2sx2"), + "evm": MustParseCid("bafk2bzacecicn2uu4wkdy23tifrevyferwfirqm2sipmmj3ctxfp3xrqntcvs"), + "init": MustParseCid("bafk2bzaceagvocld6zunqwrky2czyaao2azwbpwq7jcjv3fab5lmgbhxst5mi"), + "multisig": MustParseCid("bafk2bzaceaj27lzwb4le2rnpnughce45msvv2ezjmqiqpeazpgbzqq75jdudq"), + "paymentchannel": MustParseCid("bafk2bzaceaazgcdtp4jwezulxpuzjz76st3lumudwdvwbb5t6xzpssku5i6ha"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceds7hy7v77k2jsbkfob7b2qor6v5s2oancfxhkuuzwqqg6kxk27xe"), - "storagemarket": MustParseCid("bafk2bzacebqi6ylwfmack3hfzw6eej7r6gwlbxzo33tdkfkpof7wg7h54pjtw"), - "storageminer": MustParseCid("bafk2bzacedsxpkqqiycn5tjydycnlqer4544mpqvtwfamwyq6hwz7yjqd3iry"), - "storagepower": MustParseCid("bafk2bzacedssirrse7ufxti6capgf2qufb6y3oatv2fnnnh7xrgp47x3hfox4"), - "system": MustParseCid("bafk2bzacea2lod7lxod72voxyik5btpzmpvduddr4hwshcsyyy257izh6kut4"), - "verifiedregistry": MustParseCid("bafk2bzacebss7ol4ay6nkg7r3c2355aqpku4yvqipyh3sgdrxkhsrssrsaaig"), + "reward": MustParseCid("bafk2bzacebvqwn475gljvwlklfnmebunhsc6lj2vyr6s5qr4jehzx5de2wils"), + "storagemarket": MustParseCid("bafk2bzaceberatlfjmzke7gd3hlisvhvkduu4fbsbqymt3nyybszd34vbul32"), + "storageminer": MustParseCid("bafk2bzacedjhhhx32aec25jewhk7qhxjhsjzapi3nc2mrqbdls43hj77r3zc2"), + "storagepower": MustParseCid("bafk2bzacedhl3j7b5dzbtu772y3shmdijsiqqv36j5u2jmvb53job6curj7sk"), + "system": MustParseCid("bafk2bzaceakoq47k4ro3x4f7wd46yk6n33g2vuiiwbps5o2e5qhkhraxgvf5c"), + "verifiedregistry": MustParseCid("bafk2bzaced2fw523rkzw5rsca7a3v7isjgqyifpwxbs5dzdz5nipwes6cjdjk"), }, }, { Network: "calibrationnet", @@ -110,24 +106,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "calibrationnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacec4ilfymf3sorrfxp67ruwbax3a4mbqzic63vy2xlfh3ulky3bxvs"), + ManifestCid: MustParseCid("bafy2bzaceafl4uxyttmhccmv3246hzxu6yknal4f7ugsbpcu46kvkf6mvfvri"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacecupizfd6xbts7blvn3ozouy3f2gtehwl7qohjks54nsomtzs3aki"), - "cron": MustParseCid("bafk2bzacedry7eqweymdnybq5jm5slizm67v4ffhv7zqiw2jwevr7ijv25gjc"), - "datacap": MustParseCid("bafk2bzacebq6vigteuwchk7si6y45ogrfu2zpxjbo4a54btnbhp3rc3ifghx6"), - "eam": MustParseCid("bafk2bzacebounosssmuaz35xpyuupvijbcwqyaumbeztqmigbihfw2ysbnx4w"), - "ethaccount": MustParseCid("bafk2bzacebi2ymbi5wo2o3rp2x6cqo55vroixngmpbdcs7el4rq4hvacyzsqy"), - "evm": MustParseCid("bafk2bzaceapklwjzdzkmnfprn5wsjdzjnueuw2ke4kixq46gnbwjncns4dleu"), - "init": MustParseCid("bafk2bzaced7u4zpkxh5ecjo2emwsrk3vnickhmkxy22garqf766nbxcewymy6"), - "multisig": MustParseCid("bafk2bzacedlunqzd3mxslb7zej5fsti2jxredfhtcqqxepng67t4zfiv6lwlc"), - "paymentchannel": MustParseCid("bafk2bzacea4z2yi33rfiiutkmqko33fslikmeqgypkiam5cqpeylyp3oup552"), + "account": MustParseCid("bafk2bzaced5aa6fukm56jrjbhh5sewj2kv5mejrkjhsbx26b4xmg7x42cbkus"), + "cron": MustParseCid("bafk2bzaceautoih7urvvrubgktnmq4oqlsfqyk5mwatkj5dn42d7v7wn4hbi2"), + "datacap": MustParseCid("bafk2bzacectwanemh5tn7ojovprhag6ikvdfs4evzu2tdyg4tx6nr4qdnsyra"), + "eam": MustParseCid("bafk2bzacecxllkzu2hjcqs2br7xq7iplp4ol7ae6k4pxlwy4lzrj2b6dwaucq"), + "ethaccount": MustParseCid("bafk2bzacechpkotxlk342wp5xkpzgcz46me5nm7gdr2krfbf7zkmrgom6j4oq"), + "evm": MustParseCid("bafk2bzacedsaquz6rsixcl4bs4tdemfsxdy6rvv5klwodaetjn7iozwpkqxqa"), + "init": MustParseCid("bafk2bzaceadfoajypcb3ocklgbu6qzad2tpvrz6yrdu7kofd6wq2vssvpqnda"), + "multisig": MustParseCid("bafk2bzacecy7yahpaunojdmaxd2lposejij3sg7orn6du7zqfyuecya3uoije"), + "paymentchannel": MustParseCid("bafk2bzacebxgoj2ql5eft4sbccnj6l3ubm5qagvjmegh2atk5wrjw4xsoqy6e"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzacea4dnvun5vwzunhgepejrknukx2di2kmo3x4akz6rollq5icsrl3m"), - "storagemarket": MustParseCid("bafk2bzaceafoon3fsl756rbrih4upar3ayi6746gaj756bk56thncpotl4coa"), - "storageminer": MustParseCid("bafk2bzacea3dj37h74ue2jtief3bj2shxagigygcm2h6purgp42mr6swwfdiw"), - "storagepower": MustParseCid("bafk2bzacebmodckd4tustgfmeilcfi3ovd4wzxz2hnd6vyhkq7hgiojiy3cc6"), - "system": MustParseCid("bafk2bzacebpqirxha42noejsk5miv5kip44eay6lm63pxt26xhlwdmn7tnqaq"), - "verifiedregistry": MustParseCid("bafk2bzaceczf7qrddwt5kh3gvro25wpls346tanffeatk7nsczjnwb7jtd454"), + "reward": MustParseCid("bafk2bzaceac5aeqc7honlhs7do6n37ps56ljgx3gnoalmkz4rfy2as6nmonfu"), + "storagemarket": MustParseCid("bafk2bzacedsorzdsgjblcm7iexzxxcx5u3pqyxefn544klyv4gk357kp5fvb4"), + "storageminer": MustParseCid("bafk2bzacedvaorqhrkr3mootp4ltgzebphpqqyyj5wcyylq5dnlupxeyydagm"), + "storagepower": MustParseCid("bafk2bzacecz2u6772repwsr6x6tbbm2z4bdy4uxxlvwm6r6ggfgox6sp2buiu"), + "system": MustParseCid("bafk2bzaceafo3uoxhi6nebe3nygkmiq532cvt2iq4ikcxnioi5fqnrthnpi2q"), + "verifiedregistry": MustParseCid("bafk2bzacecw3t525evmi4g27wgqr6bowz7jgkzflr6haosej5aa3mide63edk"), }, }, { Network: "caterpillarnet", @@ -176,24 +172,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "caterpillarnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacec36gpvghhgjwa5ya3ocxg33pct2vddegeixgkpqsc6eiyajdjkii"), + ManifestCid: MustParseCid("bafy2bzaceajatwdn4jlfiweb2cuwqtnrdwdxlju2vvejlqsytocnc76xnwm2g"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebcl3xlk7i6t5tau2rfgxft5pu6qzvjqxo6zs5guerz3xarxztyv6"), - "cron": MustParseCid("bafk2bzacebhoqjvaxtzj3k4tz7c4vtt4or4u3h3jhwxlh3t4l6by2ota3s7by"), - "datacap": MustParseCid("bafk2bzaceb7ttn3d43yb7l5ok5rjgr7325jb6ds4air7mivgoyzp5p4gwgrq4"), - "eam": MustParseCid("bafk2bzacebobuasaev75fge6xg6bekrdvnyox4h7iluupt4wqq2n4expha2oe"), - "ethaccount": MustParseCid("bafk2bzaceaghtv45mm6qx3yrxwy7zz7x7mqj4n4lzw4hx7zxzlij6dcxxuv4c"), - "evm": MustParseCid("bafk2bzacecu7xpnpw27jquvnpfv4rseaal477ml4ouxy37eo7wymgfzkexllg"), - "init": MustParseCid("bafk2bzacea2rnkho4nliqvisiqgtqx66c4xneagpgj52tyqa64grxadggylbk"), - "multisig": MustParseCid("bafk2bzacebak6spthfa23cyqjmpgkgku4gg4egdn2zc6vkikbh5ongadzakma"), - "paymentchannel": MustParseCid("bafk2bzaceb3tib72pwze2rov72ldwlfv3otes3tejgnfpbrzahwb5xi7slhqm"), + "account": MustParseCid("bafk2bzacedqtev5u55huwir5pustw5ixxjzemaq67idea73mhfxb655vn6fba"), + "cron": MustParseCid("bafk2bzacec5f4javbqxjkt5lewqxs5j2it4xbwxqpcm4u5bdo6hhaibpiwad4"), + "datacap": MustParseCid("bafk2bzacec4mswfkqkvuoebimktkb3hnpl4dzclkdqyi5h7skzpl3dm73hwak"), + "eam": MustParseCid("bafk2bzacebqion6rzshb3vou32ohpat4gd2lkrihwswsthtkh3wt3ucvno3z4"), + "ethaccount": MustParseCid("bafk2bzacebnmviobduaxspr5xmmszmibs6fikdjzyxpszweooxxjxez47tr7e"), + "evm": MustParseCid("bafk2bzacebxwy5ktfrhtikwnoklcuvp4znxyh7kf2c6emdedqjtlqqnupfuqc"), + "init": MustParseCid("bafk2bzaceb37ao4tett62uxjklsaewcvauysu5he6flpk74fpfyhs4j4nlmhw"), + "multisig": MustParseCid("bafk2bzacebx6sasdjd5frk75cwcfng752f7hfdllvb5isc37zjzlsgnh2e5lq"), + "paymentchannel": MustParseCid("bafk2bzacediht5lgorndb77tr4ll2qpzziokzyuztunttod73gq6vc4fn7vrc"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceak3n3orgdraub4bqiy3paio77hu4laaqv4vf7wmwv4ybl5ahgi5o"), - "storagemarket": MustParseCid("bafk2bzacearo7sog7yqbrwyws5o3lbsdsjf2cp5vsoxc4u3s5atgjtwzzh65s"), - "storageminer": MustParseCid("bafk2bzacecrzmjrbqjwknnkybdexspb6gfu4q6dvtaeguxl26yuytsjc3w7ws"), - "storagepower": MustParseCid("bafk2bzaceavlmlu4mt2u7xwnnzf6vwdmh2yo76aauujwlgsbfhafjgxb4zgtg"), - "system": MustParseCid("bafk2bzacec35rgzpiaa4n3r5bzgssk33bhfgozjvgunbwax32dooqqokfe6ag"), - "verifiedregistry": MustParseCid("bafk2bzacebjfkrzihgzlb2jecgm5seoqwf5e656zc22vjoyclioru6vdy2bnm"), + "reward": MustParseCid("bafk2bzacebagt36uxbahizev4pelp4v57duuerqu43ejgi7i2vvofyfpkicre"), + "storagemarket": MustParseCid("bafk2bzaced5fv3zrg4iedwj2vrfzobwyyuecyb6p463pbvz7deqmpftyqpbuc"), + "storageminer": MustParseCid("bafk2bzacebs7w7oy4ef3v6em7w3pqb2ywd44eqkyqm53hqtwhatniblmoiio6"), + "storagepower": MustParseCid("bafk2bzacecbp4h5o3562myp4j7gzznc2txpdijams55kk3ctjat3hfwd64mwy"), + "system": MustParseCid("bafk2bzacea447pmvgz63rvfv3ktxf5pmi5ujq2xf4ognmoe3o7wvn6sq3cs3o"), + "verifiedregistry": MustParseCid("bafk2bzacednk3yfr7kgqfcy3mlowaoaocdcdfc6pv76akiagkircgyesiw7zs"), }, }, { Network: "devnet", @@ -233,24 +229,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "devnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacebemt6rdgtsj5vhv2iimbdvm5g4xllgl7nugxvuuthsedncmfakww"), + ManifestCid: MustParseCid("bafy2bzacedwfwgngpn52a7zzqfun37dl6brh4ue6d7y3kcs5gsz5hzbppo7ic"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzaceajmds6zbz235lbjjhv3mxc6x3kqudjkxedh5xqvlemh3f6xslz76"), - "cron": MustParseCid("bafk2bzaceabbv5ej2yd3n7txl3s4pahknb4in5dok57hzwfheqnk6k67zegbk"), - "datacap": MustParseCid("bafk2bzaceayzgq7qpuc5pr4lrh6k3xnvmirlmutffplmgur4pvcaynpxlkph6"), - "eam": MustParseCid("bafk2bzacecrand7mp7q3jm3u5dpqm4o24ki3pk3uzcw4zonjcowq4rxwptsis"), - "ethaccount": MustParseCid("bafk2bzacecpwfxpvqiyiisbfw45v5ottcstxu2vifji3xswxt3jzk4vcrs4g4"), - "evm": MustParseCid("bafk2bzaceajrtntc5urxkwbzdu3khi2eqvarnfx6vh7luqt33gn6z4a4kjkj6"), - "init": MustParseCid("bafk2bzaced6npj5zrjb3lxhgtsq4st66dvde56nftbvchmpid3rcazfvnqkpk"), - "multisig": MustParseCid("bafk2bzacealhbd4slci4o76dpdurkkk3q5busopediwfh7uis4hfh7tzghzni"), - "paymentchannel": MustParseCid("bafk2bzacebvpkvrihus53sdyutsjsbpfefe5gd2amfb6zkztdfp6g2m4ubqrk"), + "account": MustParseCid("bafk2bzacebyyteba37hzusnw6nek4cc2t3tripnpmaqcjyan4jlrosxml4us2"), + "cron": MustParseCid("bafk2bzaceddvv6uvff77qqwar76dhhzgdthsgrt66wy47a4axq2isfsu3isqa"), + "datacap": MustParseCid("bafk2bzaceapgpfwhtarq323r7ccvb2jc4yedgtdjnn5w3jgr75ayh3ctqdilk"), + "eam": MustParseCid("bafk2bzacealsu5v4552tqzwefu6htk43oixucyviwpam2can57tthwzea2erm"), + "ethaccount": MustParseCid("bafk2bzaceasdkzg5t6joexhuqiigagueb4fwkyczod5h4ipabkl5he5p6pss2"), + "evm": MustParseCid("bafk2bzacec2rienkocd7d52htiutyy26zszk5zzu47iqev3v2yca5peqgtcoc"), + "init": MustParseCid("bafk2bzacedq4e2x3zbopkxgvsryrc2lakqac6dhelt6vjqvoxqghzwmhhen2o"), + "multisig": MustParseCid("bafk2bzaceaeqphqg7jeudjwiveugre5spemixlwnvvdywdnd4hv5spj2of4is"), + "paymentchannel": MustParseCid("bafk2bzaceaey7zxzfsallib7bdinlnbysivlithvogz2nmyd2qnxcsbwfolgq"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceaftaidppnno2dzhpxl5vyti5mcmdhvheieanwvptgacuj5ozzloe"), - "storagemarket": MustParseCid("bafk2bzacea75td2k2cdwc2o4kotdods2thomhcoqg5rf62ty6gkuxojknziae"), - "storageminer": MustParseCid("bafk2bzaceapj5q7egywl3zovwcm4hpbvr4vjtoshj57ncqg3srzseweyclvug"), - "storagepower": MustParseCid("bafk2bzacebbraebsoin6hhmr4na56st4gyg7yd7p2ry2igegnvws7deq32hec"), - "system": MustParseCid("bafk2bzacedtw3mq5zyxxbnybnjegqyrz3ufiboeoipyzynlk6zgyumvl3267g"), - "verifiedregistry": MustParseCid("bafk2bzacecaqciqoky2z7win5rkzd3gkgpa3345adjyiidmg4swmw5celeb3a"), + "reward": MustParseCid("bafk2bzacec7n2iijqcrar6ztbue7sqexvuwwsif6svmzx4qfehppyom4ftyju"), + "storagemarket": MustParseCid("bafk2bzacedmyiyvcbm2zepqib5lrjxzutcc533wbkwfmcwrb5pcjsn7ucsqww"), + "storageminer": MustParseCid("bafk2bzaceai3i4ilksmjc5wmtb2hkrylrn3kfkmcyzp77vn36gc76yqor3h2i"), + "storagepower": MustParseCid("bafk2bzaceccwx5vmarswywl3spmbqfkuw4672ilsv4pyi3ytvz5vrap4ktsyk"), + "system": MustParseCid("bafk2bzacecacjaj6bgwxtywl7leqxusrcwidm6fyfibqanqgli7ueupdbib5c"), + "verifiedregistry": MustParseCid("bafk2bzacedspjal4tdnzfrn6qi4vpsikdhoeqokaizffj6lsru4kap5woyurm"), }, }, { Network: "hyperspace", @@ -274,28 +270,6 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"), "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), }, -}, { - Network: "hyperspace", - Version: 9, - ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"), - Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), - "cron": MustParseCid("bafk2bzaceahgq64awp4f7li3hdgimc4upqvdvltpmeywckvens33umcxt424a"), - "datacap": MustParseCid("bafk2bzacebkxn52ttooaslkwncijk3bgd3tm2zw7vijdhwvg2cxnxbrzmmq5e"), - "eam": MustParseCid("bafk2bzaceczhgub5anrnaf7ol65mu54gsgwcj6c6m3yhet7rhxm2l6kz4s4ru"), - "ethaccount": MustParseCid("bafk2bzacealn5enbxyxbfs7gbsjbyma2zk3bcr7okvflxhpr753d4eh6ixooa"), - "evm": MustParseCid("bafk2bzacedljkrmazyewawpnddrkzrt55556374dw2pm2hokgkompgzw4vx5y"), - "init": MustParseCid("bafk2bzacec55gyyaqjrw7zughywocgwcjvv6k5fijjpjw4xgckuqz6pjtff5a"), - "multisig": MustParseCid("bafk2bzaceblozbdzybdivvjdiid4jwm2jc6x5a66sunh2vvwsqba6wzqmr7i6"), - "paymentchannel": MustParseCid("bafk2bzacealcyke5a6n24efs6qe4iikynpk2twqssyugy7jcyf6p6shgw2iwa"), - "placeholder": MustParseCid("bafk2bzaceaamp2a35vpfml4skap4dffklzae2urcm34mtwwce2lvhaons3a5y"), - "reward": MustParseCid("bafk2bzacebafzaqhwsm3nmsfwcd6ngvx6ev6zlcpyfljqh4kb77vok6opban6"), - "storagemarket": MustParseCid("bafk2bzacecrjfg4p7fxznsdkoobs4po2ve3ywixrirrk6netgxh63qqaefamg"), - "storageminer": MustParseCid("bafk2bzaceb3ctd4atxwhdkmlg4i63zxo5aopknlj7l5kaiqr22xpcmico6vg4"), - "storagepower": MustParseCid("bafk2bzacecvcix3ugopvby2vah5wwiu5cqjedwzwkanmr34kdoc4f3o6p7nsq"), - "system": MustParseCid("bafk2bzacedo2hfopt6gy52goj7fot5qwzhtnysmgo7h25crq4clpugkerjabk"), - "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), - }, }, { Network: "mainnet", Version: 8, @@ -334,24 +308,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "mainnet", Version: 10, - ManifestCid: MustParseCid("bafy2bzacec2ggeabyyl2cjaqmcpnyvjirrrm6bfc7d73q4pekm27hybzdqs3q"), + ManifestCid: MustParseCid("bafy2bzaceanax3ruj24in364mbozrpmcyn7jf2vrxshppsgufwxemvzf6fp26"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacebdlwwnd57vd2444wrfe5amtf2f6htqj3hdh4fxblywdbynrurhgy"), - "cron": MustParseCid("bafk2bzacecxmaxh272zhgmayfg7btvq5lshv2cd7njkarlbbikba4otiaboyg"), - "datacap": MustParseCid("bafk2bzaceb64wicovvrjzaotvs64hmdtvolw4l6qanwp5tk56okzqbfttxck2"), - "eam": MustParseCid("bafk2bzacedxs56zywfumzcv7i5fwluku2qevg54cuiuwi5d3pavf3rilfu33g"), - "ethaccount": MustParseCid("bafk2bzacecepsmgsucfebvbwf5vebm7j6zeqaz3ub52warxqobqeymh5vdjik"), - "evm": MustParseCid("bafk2bzacecf6arqbso67nmrhcsjvyradrbbv7hs2noand27fyr4nfilms4znu"), - "init": MustParseCid("bafk2bzaceat2xcem5lko5ot4mmrowtm6ehx5klw7c4ss4vxma55tyfvvxwlge"), - "multisig": MustParseCid("bafk2bzacebz43omxi5vtkidhsxroqtgkpxtftdj6poew3744fayfftgdebe4y"), - "paymentchannel": MustParseCid("bafk2bzaceds4ob3ev2ie2vorhfomddd44otqfau4d4eogfofjjbjjx2h27nh2"), + "account": MustParseCid("bafk2bzacedw7633eh64r7azo5eihahnnshqs6ahfbovqfxijscpirfksw6gfe"), + "cron": MustParseCid("bafk2bzacebka3yrzfzotza5q22weufktf5azw2ew7ui5eeigxqbkzzp4ndkf2"), + "datacap": MustParseCid("bafk2bzaceawihbc7ovxq5ifj2op67u26lakybo63kgl57vyipn5rkfi4rppfq"), + "eam": MustParseCid("bafk2bzacedtzbyjyqvtvbx245uuvf4rndnbyxttavwnfo4l72oxpjiiyldh6a"), + "ethaccount": MustParseCid("bafk2bzaceapcifcyvqnbuqq2zgf4kqoypl2xj4mfqefzfp6upevmqygxayfb4"), + "evm": MustParseCid("bafk2bzaced36v7kakhej6m6jailrnojjtkqxf3ybfw4pttasxtzzczxi5fkks"), + "init": MustParseCid("bafk2bzacebqi3szlok75xn7hhtmtmnvoekwdkuhakhr4dpuxmfxvpcrhr2cog"), + "multisig": MustParseCid("bafk2bzacebsc6qdm5772h7aa6bdf3ujerpihc6cdb2zpqz4sldktk423asq2c"), + "paymentchannel": MustParseCid("bafk2bzacebxuh4n66s6vclyp73k4ee2fdxrnjouozqcf3huprobjdk6sf73g6"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaced7xvqx7n6426lls4ao54exn63pv73m7makxf7ygb575roqxhjuuw"), - "storagemarket": MustParseCid("bafk2bzaceb5piewkvdj4ee6b4qzhimixjzee5z3hsuwdjksncpvef7sgaw6rw"), - "storageminer": MustParseCid("bafk2bzaceacukfushmnsqtdvtdyx2in6o2el7jq46qo7iaxgwytel4oz5srv4"), - "storagepower": MustParseCid("bafk2bzacedi6z45jcms5guns4qxi6rs2e2prc6mpnhkr4klljrra3ayfburss"), - "system": MustParseCid("bafk2bzacedy7ssu2hez3nu7bi4j6ucojty4sfaublxlxhfd3tkgzyrm5sdxbq"), - "verifiedregistry": MustParseCid("bafk2bzacecjgudirfyzyroq3xhf2bldl636w7prexcvo7v3xqdijzcom4rgry"), + "reward": MustParseCid("bafk2bzacebwlo5udozvs7v4wbtwjtg7jdyw5g6kjws4uqfpwsqhvn6d5u6rr6"), + "storagemarket": MustParseCid("bafk2bzacebbzaj2m3hhtnpk3fz67vudb7yfyquscczksny5z2iiztp6qsbemu"), + "storageminer": MustParseCid("bafk2bzacebdb6kxpqnmiyvpgugoqtnshl362titnku6h6nmil7crodv7vjk6i"), + "storagepower": MustParseCid("bafk2bzacebqavpt7iqtcn5rlsi5cpk5l3ocrxcqcakk25hxf2zbffrzifec3w"), + "system": MustParseCid("bafk2bzacec3m3b6kktp43nrf5ow33yaehokvz2zzpa5qsrstoqwh3liv4eyba"), + "verifiedregistry": MustParseCid("bafk2bzacedufe6cnihk5anxwboprfsmbuy7nxo3peqfrdesxhgptoircbt7ca"), }, }, { Network: "testing", @@ -391,24 +365,24 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet }, { Network: "testing", Version: 10, - ManifestCid: MustParseCid("bafy2bzacedhivj4zbumou6d3242p3ecqhlqfcjfskdv46uzjchlj3ve23xyoa"), + ManifestCid: MustParseCid("bafy2bzacecdqjm4vzjqna4kvhe6ngpyimlp3qp73gjlbr3ymjaz7udkqm5k64"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), - "cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), - "datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), - "eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), - "ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), - "evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), - "init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), - "multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), - "paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), + "account": MustParseCid("bafk2bzacecfg6coqk3sn7m7g5b5akafe25qd2po4jhp5kmup4htw5iavtrca6"), + "cron": MustParseCid("bafk2bzaceblrexwzuiiqm5u77zx4xapruki3u2wzq3ca5kf72dkkv7xl3zr2a"), + "datacap": MustParseCid("bafk2bzacedbarmlig6u2tioxjqlvmlroz7pdxtqqjugtzdwg33gcsuv4zus7e"), + "eam": MustParseCid("bafk2bzacecnupv35lhealursu4osdtxjerbfqkdbugprnuctkwykmn4mlsob6"), + "ethaccount": MustParseCid("bafk2bzaceduxlxe2sasshmuvw2vzxzkkdg2e2iud6h5omcct2lszyh4xhayr2"), + "evm": MustParseCid("bafk2bzacebwhijcnwtjbyvs4czuxv6ldg3kjpv364ja3omofaacly67k4ri5k"), + "init": MustParseCid("bafk2bzaceckdouclxeccuduf42hx5draalc6iospmndsrey4mjywfv7owbdfa"), + "multisig": MustParseCid("bafk2bzacectozlgryut7dttrd6jx5uhhf5qda7tglgsoq2ccszcu34mgnpdsy"), + "paymentchannel": MustParseCid("bafk2bzacedpmrg2pseig5ollv4e6ymf7357enxflm3thsxbmz5if6anp6xpzw"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), - "storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), - "storageminer": MustParseCid("bafk2bzacecx2fs3ra4ydxvwq6oh73esqy2xjqhwsnfrdl5ctbg26zem77zy3u"), - "storagepower": MustParseCid("bafk2bzacedwfnzestwv7ylleeuk3fhp6jewc4ygw3fgodsciww7gw5ilt4ony"), - "system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), - "verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), + "reward": MustParseCid("bafk2bzacea6f7fxmfjy6bxo3jojgz7tsrmpag2pvz6yff3d4gs7jt5tr3f7ly"), + "storagemarket": MustParseCid("bafk2bzacedaopo7s23du2xosguopbjhip7zadzaquzeuhlniqgmuplsiamozq"), + "storageminer": MustParseCid("bafk2bzaceam2xfi3g7jjeby6zrauirm3cpbvfun4k2baftogckdgbrfvxsbus"), + "storagepower": MustParseCid("bafk2bzaceaeytro4ruhhhtyeatggxqpoxeqcjzg2qvutthkk4hl3wmz4xc66w"), + "system": MustParseCid("bafk2bzacedteuhprsuwcz5hqoomhy2ozyh5afmmcgughjfbak2mux3da3izvu"), + "verifiedregistry": MustParseCid("bafk2bzacedfmjez4jrix3sgpy3c3iuwemmsl446tfwwzmw7rag3imwomayzes"), }, }, { Network: "testing-fake-proofs", @@ -446,25 +420,26 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceatmqip2o3ausbntvdhj7yemu6hb3b5yqv6hm42gylbbmz7geocpm"), }, }, { - Network: "testing-fake-proofs", - Version: 10, - ManifestCid: MustParseCid("bafy2bzaceav36pezxhapk6vlgohdp6jiydk44o6xowltjnyhu3nrhpfcby5zs"), + Network: "testing-fake-proofs", + Version: 10, + BundleGitTag: "dev/20230114-pre-rc.2", + ManifestCid: MustParseCid("bafy2bzacedc2lel545tjyh66n4mrrpiomx557xeatmo2nzig3b3l22dnaxhbg"), Actors: map[string]cid.Cid{ - "account": MustParseCid("bafk2bzacea3vbptmow72euwh2meu2sgwxrxjxg53qba6xxrknltr6j7bgnlhg"), - "cron": MustParseCid("bafk2bzaceclbrnwfgolv5icdknexv3oi3ujzpt5stqabiyshwhtvnijacysjg"), - "datacap": MustParseCid("bafk2bzacebt2gym3ot447unemieakxfep3u2m2zxiqlssbacu3ifsyhtulz4m"), - "eam": MustParseCid("bafk2bzacedmnvhfvt7qc5w3mfr54ikrpwox54ddkxkxp5qka24xudj4vkggjs"), - "ethaccount": MustParseCid("bafk2bzacebnh3oadihryhwgo73ooesgk3x2eg4g5gorps463iirilm5ur4q7w"), - "evm": MustParseCid("bafk2bzacecw2i5bsjymtdblvxh5xte3htff4przqaek673cw5z7ommaptdmqq"), - "init": MustParseCid("bafk2bzacebo6n4pwpwayjsc7cbrmmjy6l6om3wzx5jdldni4wl47a4x4jeazo"), - "multisig": MustParseCid("bafk2bzacecl4mc5esjwfcoirhdeqhms4qquafam4ut424hj2mo3gqzb47n2rs"), - "paymentchannel": MustParseCid("bafk2bzacedsmvdirjuywbg5xz7r5u2pxew7ye4kpy2toksv5nba7dzkcsmu3i"), + "account": MustParseCid("bafk2bzacecfg6coqk3sn7m7g5b5akafe25qd2po4jhp5kmup4htw5iavtrca6"), + "cron": MustParseCid("bafk2bzaceblrexwzuiiqm5u77zx4xapruki3u2wzq3ca5kf72dkkv7xl3zr2a"), + "datacap": MustParseCid("bafk2bzacedbarmlig6u2tioxjqlvmlroz7pdxtqqjugtzdwg33gcsuv4zus7e"), + "eam": MustParseCid("bafk2bzacecnupv35lhealursu4osdtxjerbfqkdbugprnuctkwykmn4mlsob6"), + "ethaccount": MustParseCid("bafk2bzaceduxlxe2sasshmuvw2vzxzkkdg2e2iud6h5omcct2lszyh4xhayr2"), + "evm": MustParseCid("bafk2bzacebwhijcnwtjbyvs4czuxv6ldg3kjpv364ja3omofaacly67k4ri5k"), + "init": MustParseCid("bafk2bzaceckdouclxeccuduf42hx5draalc6iospmndsrey4mjywfv7owbdfa"), + "multisig": MustParseCid("bafk2bzacectozlgryut7dttrd6jx5uhhf5qda7tglgsoq2ccszcu34mgnpdsy"), + "paymentchannel": MustParseCid("bafk2bzacedpmrg2pseig5ollv4e6ymf7357enxflm3thsxbmz5if6anp6xpzw"), "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), - "reward": MustParseCid("bafk2bzaceakq4np44ltnscgff7h3a6s6ao2d43vwx66tce5r57r2amw42pl5i"), - "storagemarket": MustParseCid("bafk2bzacebskzlyhvhrdheslyrez3p4sccr5t42xnqophnvj775roskwzoic4"), - "storageminer": MustParseCid("bafk2bzacebp3rj6d4g2ppngw2xp7okzqx6oapfk6xi54n3aqenadqvptlk45g"), - "storagepower": MustParseCid("bafk2bzacedhwtksxb6orm63doxx2bgcy6fpy5li5prjb3twsxdh75anjbmdug"), - "system": MustParseCid("bafk2bzaceaql3e6266ixcbwcdmwuhod4tahhawlvhfkq4qzp7hnmkkybdf7zi"), - "verifiedregistry": MustParseCid("bafk2bzacecibid6xpyu64kaxk2mspouajnenxlh4jkny7d6l5ht3hxg67l32u"), + "reward": MustParseCid("bafk2bzacea6f7fxmfjy6bxo3jojgz7tsrmpag2pvz6yff3d4gs7jt5tr3f7ly"), + "storagemarket": MustParseCid("bafk2bzacedaopo7s23du2xosguopbjhip7zadzaquzeuhlniqgmuplsiamozq"), + "storageminer": MustParseCid("bafk2bzacecweqgs7k452vertmz66hjz2ymrgdbn4ycduyho3znoqv56ay4xlw"), + "storagepower": MustParseCid("bafk2bzaceapnz6icrfdgjcr7d2rknak5wirxxbh7mmo7kfutacxys22xrapbe"), + "system": MustParseCid("bafk2bzacedteuhprsuwcz5hqoomhy2ozyh5afmmcgughjfbak2mux3da3izvu"), + "verifiedregistry": MustParseCid("bafk2bzacedfmjez4jrix3sgpy3c3iuwemmsl446tfwwzmw7rag3imwomayzes"), }, }} diff --git a/build/builtin_actors_test.go b/build/builtin_actors_test.go index 858a8b3a1..bb133bdab 100644 --- a/build/builtin_actors_test.go +++ b/build/builtin_actors_test.go @@ -17,7 +17,13 @@ func TestEmbeddedMetadata(t *testing.T) { metadata, err := build.ReadEmbeddedBuiltinActorsMetadata() require.NoError(t, err) - require.Equal(t, metadata, build.EmbeddedBuiltinActorsMetadata) + for i, v1 := range metadata { + v2 := build.EmbeddedBuiltinActorsMetadata[i] + require.Equal(t, v1.Network, v2.Network) + require.Equal(t, v1.Version, v2.Version) + require.Equal(t, v1.ManifestCid, v2.ManifestCid) + require.Equal(t, v1.Actors, v2.Actors) + } } // Test that we're registering the manifest correctly. diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index ddeb9c9a3..a33ab9ab3 100644 Binary files a/build/openrpc/full.json.gz and b/build/openrpc/full.json.gz differ diff --git a/build/openrpc/gateway.json.gz b/build/openrpc/gateway.json.gz index 790c44fc4..f8dc51639 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/build/params_butterfly.go b/build/params_butterfly.go index 7cd02bce9..b00381b44 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -19,7 +19,7 @@ var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } -const GenesisNetworkVersion = network.Version16 +const GenesisNetworkVersion = network.Version17 var NetworkBundle = "butterflynet" var BundleOverrides map[actorstypes.Version]string diff --git a/chain/actors/builtin/evm/actor.go.template b/chain/actors/builtin/evm/actor.go.template index d20db6bcb..aa23b5f11 100644 --- a/chain/actors/builtin/evm/actor.go.template +++ b/chain/actors/builtin/evm/actor.go.template @@ -49,4 +49,8 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecode() ([]byte, error) + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go index 120ca66f8..f55a2177d 100644 --- a/chain/actors/builtin/evm/evm.go +++ b/chain/actors/builtin/evm/evm.go @@ -49,4 +49,8 @@ type State interface { Nonce() (uint64, error) GetState() interface{} + + GetBytecode() ([]byte, error) + GetBytecodeCID() (cid.Cid, error) + GetBytecodeHash() ([32]byte, error) } diff --git a/chain/actors/builtin/evm/state.go.template b/chain/actors/builtin/evm/state.go.template index acc78dc0f..eb55a8463 100644 --- a/chain/actors/builtin/evm/state.go.template +++ b/chain/actors/builtin/evm/state.go.template @@ -21,12 +21,12 @@ func load{{.v}}(store adt.Store, root cid.Cid) (State, error) { func make{{.v}}(store adt.Store, bytecode cid.Cid) (State, error) { out := state{{.v}}{store: store} - s, err := evm{{.v}}.ConstructState(store, bytecode) - if err != nil { - return nil, err - } + s, err := evm{{.v}}.ConstructState(store, bytecode) + if err != nil { + return nil, err + } - out.State = *s + out.State = *s return &out, nil } @@ -42,4 +42,26 @@ func (s *state{{.v}}) Nonce() (uint64, error) { func (s *state{{.v}}) GetState() interface{} { return &s.State -} \ No newline at end of file +} + +func (s *state{{.v}}) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state{{.v}}) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state{{.v}}) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/chain/actors/builtin/evm/v10.go b/chain/actors/builtin/evm/v10.go index 78a4a2383..77a09037b 100644 --- a/chain/actors/builtin/evm/v10.go +++ b/chain/actors/builtin/evm/v10.go @@ -3,6 +3,7 @@ package evm import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" evm10 "github.com/filecoin-project/go-state-types/builtin/v10/evm" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -43,3 +44,25 @@ func (s *state10) Nonce() (uint64, error) { func (s *state10) GetState() interface{} { return &s.State } + +func (s *state10) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state10) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state10) GetBytecode() ([]byte, error) { + bc, err := s.GetBytecodeCID() + if err != nil { + return nil, err + } + + var byteCode abi.CborBytesTransparent + if err := s.store.Get(s.store.Context(), bc, &byteCode); err != nil { + return nil, err + } + + return byteCode, nil +} diff --git a/chain/events/filter/event.go b/chain/events/filter/event.go index dfb61f111..b821a2f83 100644 --- a/chain/events/filter/event.go +++ b/chain/events/filter/event.go @@ -105,18 +105,9 @@ func (f *EventFilter) CollectEvents(ctx context.Context, te *TipSetEvents, rever continue } - entries := make([]types.EventEntry, len(ev.Entries)) - for i, entry := range ev.Entries { - entries[i] = types.EventEntry{ - Flags: entry.Flags, - Key: entry.Key, - Value: entry.Value, - } - } - // event matches filter, so record it cev := &CollectedEvent{ - Entries: entries, + Entries: ev.Entries, EmitterAddr: addr, EventIdx: evIdx, Reverted: revert, diff --git a/chain/events/filter/event_test.go b/chain/events/filter/event_test.go index 80c4c7fc0..329573bc1 100644 --- a/chain/events/filter/event_test.go +++ b/chain/events/filter/event_test.go @@ -287,6 +287,7 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event { ev.Entries = append(ev.Entries, types.EventEntry{ Flags: 0x01, Key: in.k, + Codec: cid.Raw, Value: in.v, }) } @@ -295,6 +296,7 @@ func fakeEvent(emitter abi.ActorID, indexed []kv, unindexed []kv) *types.Event { ev.Entries = append(ev.Entries, types.EventEntry{ Flags: 0x00, Key: in.k, + Codec: cid.Raw, Value: in.v, }) } diff --git a/chain/events/filter/index.go b/chain/events/filter/index.go index 1b69dfd10..ab4e24493 100644 --- a/chain/events/filter/index.go +++ b/chain/events/filter/index.go @@ -47,6 +47,7 @@ var ddls = []string{ indexed INTEGER NOT NULL, flags BLOB NOT NULL, key TEXT NOT NULL, + codec INTEGER, value BLOB NOT NULL )`, @@ -67,8 +68,8 @@ const ( VALUES(?, ?, ?, ?, ?, ?, ?, ?)` insertEntry = `INSERT OR IGNORE INTO event_entry - (event_id, indexed, flags, key, value) - VALUES(?, ?, ?, ?, ?)` + (event_id, indexed, flags, key, codec, value) + VALUES(?, ?, ?, ?, ?, ?)` ) type EventIndex struct { @@ -194,6 +195,7 @@ func (ei *EventIndex) CollectEvents(ctx context.Context, te *TipSetEvents, rever isIndexedValue(entry.Flags), // indexed []byte{entry.Flags}, // flags entry.Key, // key + entry.Codec, // codec entry.Value, // value ) if err != nil { @@ -251,7 +253,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { subclauses := []string{} for _, val := range vals { subclauses = append(subclauses, fmt.Sprintf("%s.value=?", joinAlias)) - values = append(values, trimLeadingZeros(val)) + values = append(values, val) } clauses = append(clauses, "("+strings.Join(subclauses, " OR ")+")") } @@ -270,6 +272,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { event.reverted, event_entry.flags, event_entry.key, + event_entry.codec, event_entry.value FROM event JOIN event_entry ON event.id=event_entry.event_id` @@ -319,6 +322,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { reverted bool flags []byte key string + codec uint64 value []byte } @@ -334,6 +338,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { &row.reverted, &row.flags, &row.key, + &row.codec, &row.value, ); err != nil { return xerrors.Errorf("read prefill row: %w", err) @@ -378,6 +383,7 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { ce.Entries = append(ce.Entries, types.EventEntry{ Flags: row.flags[0], Key: row.key, + Codec: row.codec, Value: row.value, }) @@ -398,12 +404,3 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { return nil } - -func trimLeadingZeros(b []byte) []byte { - for i := range b { - if b[i] != 0 { - return b[i:] - } - } - return []byte{} -} diff --git a/chain/store/messages.go b/chain/store/messages.go index 5e2880c4a..1ee1f8ad4 100644 --- a/chain/store/messages.go +++ b/chain/store/messages.go @@ -256,6 +256,20 @@ func (cs *ChainStore) MessagesForBlock(ctx context.Context, b *types.BlockHeader return blsmsgs, secpkmsgs, nil } +func (cs *ChainStore) SecpkMessagesForBlock(ctx context.Context, b *types.BlockHeader) ([]*types.SignedMessage, error) { + _, secpkcids, err := cs.ReadMsgMetaCids(ctx, b.Messages) + if err != nil { + return nil, err + } + + secpkmsgs, err := cs.LoadSignedMessagesFromCids(ctx, secpkcids) + if err != nil { + return nil, xerrors.Errorf("loading secpk messages for block: %w", err) + } + + return secpkmsgs, nil +} + func (cs *ChainStore) GetParentReceipt(ctx context.Context, b *types.BlockHeader, i int) (*types.MessageReceipt, error) { // block headers use adt0, for now. a, err := blockadt.AsArray(cs.ActorStore(ctx), b.ParentMessageReceipts) diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 709f7dd88..314b2be6c 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -1943,7 +1943,7 @@ func (t *Event) UnmarshalCBOR(r io.Reader) (err error) { return nil } -var lengthBufEventEntry = []byte{131} +var lengthBufEventEntry = []byte{132} func (t *EventEntry) MarshalCBOR(w io.Writer) error { if t == nil { @@ -1974,6 +1974,12 @@ func (t *EventEntry) MarshalCBOR(w io.Writer) error { return err } + // t.Codec (uint64) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Codec)); err != nil { + return err + } + // t.Value ([]uint8) (slice) if len(t.Value) > cbg.ByteArrayMaxLen { return xerrors.Errorf("Byte array in field t.Value was too long") @@ -2008,7 +2014,7 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) { return fmt.Errorf("cbor input should be of type array") } - if extra != 3 { + if extra != 4 { return fmt.Errorf("cbor input had wrong number of fields") } @@ -2035,6 +2041,20 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) { t.Key = string(sval) } + // t.Codec (uint64) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Codec = uint64(extra) + + } // t.Value ([]uint8) (slice) maj, extra, err = cr.ReadHeader() diff --git a/chain/types/ethtypes/eth_transactions.go b/chain/types/ethtypes/eth_transactions.go index 9f9df2381..5c2283d2b 100644 --- a/chain/types/ethtypes/eth_transactions.go +++ b/chain/types/ethtypes/eth_transactions.go @@ -37,7 +37,8 @@ type EthTx struct { Gas EthUint64 `json:"gas"` MaxFeePerGas EthBigInt `json:"maxFeePerGas"` MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"` - V EthBigInt `json:"v"` + AccessList []EthHash `json:"accessList"` + V EthBigInt `json:"yParity"` R EthBigInt `json:"r"` S EthBigInt `json:"s"` } @@ -86,6 +87,7 @@ func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) { Gas: EthUint64(txArgs.GasLimit), MaxFeePerGas: EthBigInt(txArgs.MaxFeePerGas), MaxPriorityFeePerGas: EthBigInt(txArgs.MaxPriorityFeePerGas), + AccessList: []EthHash{}, V: v, R: r, S: s, diff --git a/chain/types/ethtypes/eth_types.go b/chain/types/ethtypes/eth_types.go index 45ae46c59..ea083f6c1 100644 --- a/chain/types/ethtypes/eth_types.go +++ b/chain/types/ethtypes/eth_types.go @@ -22,6 +22,7 @@ import ( builtintypes "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/lib/must" ) var ( @@ -144,7 +145,7 @@ type EthBlock struct { GasLimit EthUint64 `json:"gasLimit"` GasUsed EthUint64 `json:"gasUsed"` Timestamp EthUint64 `json:"timestamp"` - Extradata []byte `json:"extraData"` + Extradata EthBytes `json:"extraData"` MixHash EthHash `json:"mixHash"` Nonce EthNonce `json:"nonce"` BaseFeePerGas EthBigInt `json:"baseFeePerGas"` @@ -154,21 +155,32 @@ type EthBlock struct { Uncles []EthHash `json:"uncles"` } +const EthBloomSize = 2048 + var ( - EmptyEthBloom = [256]byte{} - EmptyEthHash = EthHash{} - EmptyEthInt = EthUint64(0) - EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} + EmptyEthBloom = [EthBloomSize / 8]byte{} + FullEthBloom = [EthBloomSize / 8]byte{} + EmptyEthHash = EthHash{} + EmptyUncleHash = must.One(ParseEthHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")) // Keccak-256 of an RLP of an empty array + EmptyRootHash = must.One(ParseEthHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421")) // Keccak-256 hash of the RLP of null + EmptyEthInt = EthUint64(0) + EmptyEthNonce = [8]byte{0, 0, 0, 0, 0, 0, 0, 0} ) -func NewEthBlock() EthBlock { - return EthBlock{ - Sha3Uncles: EmptyEthHash, +func init() { + for i := range FullEthBloom { + FullEthBloom[i] = 0xff + } +} + +func NewEthBlock(hasTransactions bool) EthBlock { + b := EthBlock{ + Sha3Uncles: EmptyUncleHash, // Sha3Uncles set to a hardcoded value which is used by some clients to determine if has no uncles. StateRoot: EmptyEthHash, - TransactionsRoot: EmptyEthHash, + TransactionsRoot: EmptyRootHash, // TransactionsRoot set to a hardcoded value which is used by some clients to determine if has no transactions. ReceiptsRoot: EmptyEthHash, Difficulty: EmptyEthInt, - LogsBloom: EmptyEthBloom[:], + LogsBloom: FullEthBloom[:], Extradata: []byte{}, MixHash: EmptyEthHash, Nonce: EmptyEthNonce, @@ -176,6 +188,11 @@ func NewEthBlock() EthBlock { Uncles: []EthHash{}, Transactions: []interface{}{}, } + if hasTransactions { + b.TransactionsRoot = EmptyEthHash + } + + return b } type EthCall struct { @@ -396,6 +413,10 @@ func DecodeHexString(s string) ([]byte, error) { return b, nil } +func DecodeHexStringTrimSpace(s string) ([]byte, error) { + return DecodeHexString(strings.TrimSpace(s)) +} + func handleHexStringPrefix(s string) string { // Strip the leading 0x or 0X prefix since hex.DecodeString does not support it. if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { @@ -432,8 +453,19 @@ func EthHashFromTxBytes(b []byte) EthHash { return ethHash } +func EthBloomSet(f EthBytes, data []byte) { + hasher := sha3.NewLegacyKeccak256() + hasher.Write(data) + hash := hasher.Sum(nil) + + for i := 0; i < 3; i++ { + n := binary.BigEndian.Uint16(hash[i*2:]) % EthBloomSize + f[(EthBloomSize/8)-(n/8)-1] |= 1 << (n % 8) + } +} + type EthFeeHistory struct { - OldestBlock uint64 `json:"oldestBlock"` + OldestBlock EthUint64 `json:"oldestBlock"` BaseFeePerGas []EthBigInt `json:"baseFeePerGas"` GasUsedRatio []float64 `json:"gasUsedRatio"` Reward *[][]EthBigInt `json:"reward,omitempty"` diff --git a/chain/types/event.go b/chain/types/event.go index 20c6fd852..91b0e95d3 100644 --- a/chain/types/event.go +++ b/chain/types/event.go @@ -30,7 +30,10 @@ type EventEntry struct { // The key of this event entry Key string - // Any DAG-CBOR encodeable type. + // The event value's codec + Codec uint64 + + // The event value Value []byte } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 2dd1f37e6..cea17f61d 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -291,7 +291,7 @@ func DumpActorState(i *ActorRegistry, act *types.Actor, b []byte) (interface{}, um := actInfo.vmActor.State() if um == nil { - if act.Code != EmptyObjectCid { + if act.Head != EmptyObjectCid { return nil, xerrors.Errorf("actor with code %s should only have empty object (%s) as its Head, instead has %s", act.Code, EmptyObjectCid, act.Head) } diff --git a/cli/evm.go b/cli/evm.go index 1c02f92b4..2169a3486 100644 --- a/cli/evm.go +++ b/cli/evm.go @@ -107,7 +107,7 @@ var EvmCallSimulateCmd = &cli.Command{ return err } - params, err := ethtypes.DecodeHexString(cctx.Args().Get(2)) + params, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(2)) if err != nil { return err } @@ -151,7 +151,7 @@ var EvmGetContractAddress = &cli.Command{ return err } - salt, err := ethtypes.DecodeHexString(cctx.Args().Get(1)) + salt, err := ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1)) if err != nil { return xerrors.Errorf("Could not decode salt: %w", err) } @@ -170,7 +170,7 @@ var EvmGetContractAddress = &cli.Command{ return err } - contract, err := ethtypes.DecodeHexString(string(contractHex)) + contract, err := ethtypes.DecodeHexStringTrimSpace(string(contractHex)) if err != nil { return xerrors.Errorf("Could not decode contract file: %w", err) } @@ -219,7 +219,7 @@ var EvmDeployCmd = &cli.Command{ return xerrors.Errorf("failed to read contract: %w", err) } if cctx.Bool("hex") { - contract, err = ethtypes.DecodeHexString(string(contract)) + contract, err = ethtypes.DecodeHexStringTrimSpace(string(contract)) if err != nil { return xerrors.Errorf("failed to decode contract: %w", err) } @@ -341,7 +341,7 @@ var EvmInvokeCmd = &cli.Command{ } var calldata []byte - calldata, err = ethtypes.DecodeHexString(cctx.Args().Get(1)) + calldata, err = ethtypes.DecodeHexStringTrimSpace(cctx.Args().Get(1)) if err != nil { return xerrors.Errorf("decoding hex input data: %w", err) } diff --git a/cli/send.go b/cli/send.go index 3e390584d..e18aa544e 100644 --- a/cli/send.go +++ b/cli/send.go @@ -117,6 +117,17 @@ var sendCmd = &cli.Command{ params.From = faddr } + if params.From.Protocol() == address.Delegated { + if !(params.To.Protocol() == address.ID || params.To.Protocol() == address.Delegated) { + api := srv.FullNodeAPI() + // Resolve id addr if possible. + params.To, err = api.StateLookupID(ctx, params.To, types.EmptyTSK) + if err != nil { + return xerrors.Errorf("f4 addresses can only send to other f4 or id addresses. could not find id address for %s", params.To.String()) + } + } + } + if cctx.IsSet("gas-premium") { gp, err := types.BigFromString(cctx.String("gas-premium")) if err != nil { diff --git a/cli/state.go b/cli/state.go index c69299946..3d629bb0b 100644 --- a/cli/state.go +++ b/cli/state.go @@ -1354,7 +1354,7 @@ func ComputeStateHTMLTempl(w io.Writer, ts *types.TipSet, o *api.ComputeStateOut "GetMethod": getMethod, "ToFil": toFil, "JsonParams": JsonParams, - "JsonReturn": jsonReturn, + "JsonReturn": JsonReturn, "IsSlow": isSlow, "IsVerySlow": isVerySlow, "IntExit": func(i exitcode.ExitCode) int64 { return int64(i) }, @@ -1440,7 +1440,7 @@ func JsonParams(code cid.Cid, method abi.MethodNum, params []byte) (string, erro return string(b), err } -func jsonReturn(code cid.Cid, method abi.MethodNum, ret []byte) (string, error) { +func JsonReturn(code cid.Cid, method abi.MethodNum, ret []byte) (string, error) { methodMeta, found := filcns.NewActorRegistry().Methods[code][method] // TODO: use remote if !found { return "", fmt.Errorf("method %d not found on actor %s", method, code) @@ -1549,7 +1549,7 @@ func printReceiptReturn(ctx context.Context, api v0api.FullNode, m *types.Messag return err } - jret, err := jsonReturn(act.Code, m.Method, r.Return) + jret, err := JsonReturn(act.Code, m.Method, r.Return) if err != nil { return err } @@ -1689,7 +1689,7 @@ var StateCallCmd = &cli.Command{ return xerrors.Errorf("getting actor: %w", err) } - retStr, err := jsonReturn(act.Code, abi.MethodNum(method), ret.MsgRct.Return) + retStr, err := JsonReturn(act.Code, abi.MethodNum(method), ret.MsgRct.Return) if err != nil { return xerrors.Errorf("decoding return: %w", err) } diff --git a/cmd/lotus-shed/balances.go b/cmd/lotus-shed/balances.go index 9ce4faf72..c647f3b8e 100644 --- a/cmd/lotus-shed/balances.go +++ b/cmd/lotus-shed/balances.go @@ -454,8 +454,9 @@ var chainBalanceStateCmd = &cli.Command{ Description: "Produces a csv file of all account balances from a given stateroot", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "miner-info", @@ -677,8 +678,9 @@ var chainPledgeCmd = &cli.Command{ Description: "Calculate sector pledge numbers", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, ArgsUsage: "[stateroot epoch]", diff --git a/cmd/lotus-shed/datastore.go b/cmd/lotus-shed/datastore.go index 5614e34f6..d6b932954 100644 --- a/cmd/lotus-shed/datastore.go +++ b/cmd/lotus-shed/datastore.go @@ -41,6 +41,11 @@ var datastoreListCmd = &cli.Command{ Name: "list", Description: "list datastore keys", Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, &cli.StringFlag{ Name: "repo-type", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", @@ -110,6 +115,11 @@ var datastoreGetCmd = &cli.Command{ Name: "get", Description: "list datastore keys", Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, &cli.StringFlag{ Name: "repo-type", Usage: "node type (FullNode, StorageMiner, Worker, Wallet)", @@ -123,7 +133,7 @@ var datastoreGetCmd = &cli.Command{ }, ArgsUsage: "[namespace key]", Action: func(cctx *cli.Context) error { - logging.SetLogLevel("badger", "ERROR") // nolint:errcheck + _ = logging.SetLogLevel("badger", "ERROR") r, err := repo.NewFS(cctx.String("repo")) if err != nil { diff --git a/cmd/lotus-shed/deal-label.go b/cmd/lotus-shed/deal-label.go index 417d13701..2baa751a9 100644 --- a/cmd/lotus-shed/deal-label.go +++ b/cmd/lotus-shed/deal-label.go @@ -24,8 +24,9 @@ var dealLabelCmd = &cli.Command{ Usage: "Scrape state to report on how many deals have non UTF-8 labels", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/diff.go b/cmd/lotus-shed/diff.go index 981dc850c..e29d9ca6d 100644 --- a/cmd/lotus-shed/diff.go +++ b/cmd/lotus-shed/diff.go @@ -33,8 +33,9 @@ var diffMinerStates = &cli.Command{ ArgsUsage: " ", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/export-car.go b/cmd/lotus-shed/export-car.go index 5cb4737ea..e32dbb2cf 100644 --- a/cmd/lotus-shed/export-car.go +++ b/cmd/lotus-shed/export-car.go @@ -35,8 +35,9 @@ var exportCarCmd = &cli.Command{ Description: "Export a car from repo", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, ArgsUsage: "[outfile] [root cid]", diff --git a/cmd/lotus-shed/export.go b/cmd/lotus-shed/export.go index 459de3383..ab6d88698 100644 --- a/cmd/lotus-shed/export.go +++ b/cmd/lotus-shed/export.go @@ -42,8 +42,9 @@ var exportChainCmd = &cli.Command{ Description: "Export chain from repo (requires node to be offline)", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "tipset", @@ -146,8 +147,9 @@ var exportRawCmd = &cli.Command{ Description: "Export raw blocks from repo (requires node to be offline)", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "car-size", diff --git a/cmd/lotus-shed/fip-0036.go b/cmd/lotus-shed/fip-0036.go index 485302b9b..1929eb4dd 100644 --- a/cmd/lotus-shed/fip-0036.go +++ b/cmd/lotus-shed/fip-0036.go @@ -58,12 +58,6 @@ var fip36PollCmd = &cli.Command{ Name: "fip36poll", Usage: "Process the FIP0036 FilPoll result", ArgsUsage: "[state root, votes]", - Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", - }, - }, Subcommands: []*cli.Command{ finalResultCmd, }, @@ -75,8 +69,9 @@ var finalResultCmd = &cli.Command{ ArgsUsage: "[state root] [height] [votes json]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, diff --git a/cmd/lotus-shed/gas-estimation.go b/cmd/lotus-shed/gas-estimation.go index cf56ea03d..669c1c345 100644 --- a/cmd/lotus-shed/gas-estimation.go +++ b/cmd/lotus-shed/gas-estimation.go @@ -42,8 +42,9 @@ var gasTraceCmd = &cli.Command{ ArgsUsage: "[migratedStateRootCid networkVersion messageCid]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { @@ -146,8 +147,9 @@ var replayOfflineCmd = &cli.Command{ ArgsUsage: "[messageCid]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.Int64Flag{ Name: "lookback-limit", diff --git a/cmd/lotus-shed/import-car.go b/cmd/lotus-shed/import-car.go index 973e7b31b..6bba1d980 100644 --- a/cmd/lotus-shed/import-car.go +++ b/cmd/lotus-shed/import-car.go @@ -19,6 +19,13 @@ import ( var importCarCmd = &cli.Command{ Name: "import-car", Description: "Import a car file into node chain blockstore", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { @@ -96,6 +103,13 @@ var importCarCmd = &cli.Command{ var importObjectCmd = &cli.Command{ Name: "import-obj", Usage: "import a raw ipld object into your datastore", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { r, err := repo.NewFS(cctx.String("repo")) if err != nil { diff --git a/cmd/lotus-shed/invariants.go b/cmd/lotus-shed/invariants.go index e48f301c4..953674ed0 100644 --- a/cmd/lotus-shed/invariants.go +++ b/cmd/lotus-shed/invariants.go @@ -35,8 +35,9 @@ var invariantsCmd = &cli.Command{ ArgsUsage: "[StateRootCid, height]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/keyinfo.go b/cmd/lotus-shed/keyinfo.go index 38f5ee6fe..1c322f7d6 100644 --- a/cmd/lotus-shed/keyinfo.go +++ b/cmd/lotus-shed/keyinfo.go @@ -146,9 +146,14 @@ var keyinfoImportCmd = &cli.Command{ Examples env LOTUS_PATH=/var/lib/lotus lotus-shed keyinfo import libp2p-host.keyinfo`, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, + }, + }, Action: func(cctx *cli.Context) error { - flagRepo := cctx.String("repo") - var input io.Reader if cctx.NArg() == 0 { input = os.Stdin @@ -177,7 +182,7 @@ var keyinfoImportCmd = &cli.Command{ return err } - fsrepo, err := repo.NewFS(flagRepo) + fsrepo, err := repo.NewFS(cctx.String("repo")) if err != nil { return err } diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 28a59f14d..c0d0043f1 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "os" logging "github.com/ipfs/go-log/v2" @@ -89,19 +88,6 @@ func main() { Version: build.UserVersion(), Commands: local, Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"LOTUS_PATH"}, - Hidden: true, - Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME - }, - &cli.StringFlag{ - Name: "miner-repo", - Aliases: []string{"storagerepo"}, - EnvVars: []string{"LOTUS_MINER_PATH", "LOTUS_STORAGE_PATH"}, - Value: "~/.lotusminer", // TODO: Consider XDG_DATA_HOME - Usage: fmt.Sprintf("Specify miner repo path. flag storagerepo and env LOTUS_STORAGE_PATH are DEPRECATION, will REMOVE SOON"), - }, &cli.StringFlag{ Name: "log-level", Value: "info", diff --git a/cmd/lotus-shed/market.go b/cmd/lotus-shed/market.go index 0c5e7c81d..6d86c90b9 100644 --- a/cmd/lotus-shed/market.go +++ b/cmd/lotus-shed/market.go @@ -124,8 +124,9 @@ var marketExportDatastoreCmd = &cli.Command{ Description: "export markets datastore key/values to a file", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Usage: "path to the repo", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "backup-dir", @@ -241,8 +242,9 @@ var marketImportDatastoreCmd = &cli.Command{ Description: "import markets datastore key/values from a backup file", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Usage: "path to the repo", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.StringFlag{ Name: "backup-path", diff --git a/cmd/lotus-shed/migrations.go b/cmd/lotus-shed/migrations.go index a7e0ee34f..e0336283a 100644 --- a/cmd/lotus-shed/migrations.go +++ b/cmd/lotus-shed/migrations.go @@ -54,8 +54,9 @@ var migrationsCmd = &cli.Command{ ArgsUsage: "[new network version, block to look back from]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "skip-pre-migration", diff --git a/cmd/lotus-shed/miner-peerid.go b/cmd/lotus-shed/miner-peerid.go index e43063797..fdf8dae8d 100644 --- a/cmd/lotus-shed/miner-peerid.go +++ b/cmd/lotus-shed/miner-peerid.go @@ -26,10 +26,12 @@ import ( var minerPeeridCmd = &cli.Command{ Name: "miner-peerid", - Usage: "Scrape state to find a miner based on peerid", Flags: []cli.Flag{ + Usage: "Scrape state to find a miner based on peerid", + Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/miner-types.go b/cmd/lotus-shed/miner-types.go index 822d037aa..15e5db265 100644 --- a/cmd/lotus-shed/miner-types.go +++ b/cmd/lotus-shed/miner-types.go @@ -28,10 +28,12 @@ import ( var minerTypesCmd = &cli.Command{ Name: "miner-types", - Usage: "Scrape state to report on how many miners of each WindowPoStProofType exist", Flags: []cli.Flag{ + Usage: "Scrape state to report on how many miners of each WindowPoStProofType exist", + Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/msig.go b/cmd/lotus-shed/msig.go index ccc932c93..96ba91219 100644 --- a/cmd/lotus-shed/msig.go +++ b/cmd/lotus-shed/msig.go @@ -43,8 +43,9 @@ var multisigGetAllCmd = &cli.Command{ ArgsUsage: "[state root]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/cmd/lotus-shed/nonce-fix.go b/cmd/lotus-shed/nonce-fix.go index d69c8a48d..d68f22e0b 100644 --- a/cmd/lotus-shed/nonce-fix.go +++ b/cmd/lotus-shed/nonce-fix.go @@ -17,12 +17,6 @@ import ( var noncefix = &cli.Command{ Name: "noncefix", Flags: []cli.Flag{ - &cli.StringFlag{ - Name: "repo", - EnvVars: []string{"LOTUS_PATH"}, - Hidden: true, - Value: "~/.lotus", // TODO: Consider XDG_DATA_HOME - }, &cli.Uint64Flag{ Name: "start", }, diff --git a/cmd/lotus-shed/pruning.go b/cmd/lotus-shed/pruning.go index 275f3bc0a..1b6553057 100644 --- a/cmd/lotus-shed/pruning.go +++ b/cmd/lotus-shed/pruning.go @@ -86,8 +86,9 @@ var stateTreePruneCmd = &cli.Command{ Description: "Deletes old state root data from local chainstore", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.Int64Flag{ Name: "keep-from-lookback", diff --git a/cmd/lotus-shed/splitstore.go b/cmd/lotus-shed/splitstore.go index e8c45a0c5..348f2e36d 100644 --- a/cmd/lotus-shed/splitstore.go +++ b/cmd/lotus-shed/splitstore.go @@ -39,8 +39,9 @@ var splitstoreRollbackCmd = &cli.Command{ Description: "rollbacks a splitstore installation", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "gc-coldstore", @@ -129,8 +130,9 @@ var splitstoreClearCmd = &cli.Command{ Description: "clears a splitstore installation for restart from snapshot", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, &cli.BoolFlag{ Name: "keys-only", diff --git a/cmd/lotus-shed/terminations.go b/cmd/lotus-shed/terminations.go index c5f35995a..c9e3d26bb 100644 --- a/cmd/lotus-shed/terminations.go +++ b/cmd/lotus-shed/terminations.go @@ -33,8 +33,9 @@ var terminationsCmd = &cli.Command{ ArgsUsage: "[block to look back from] [lookback period (epochs)]", Flags: []cli.Flag{ &cli.StringFlag{ - Name: "repo", - Value: "~/.lotus", + Name: "repo", + Value: "~/.lotus", + EnvVars: []string{"LOTUS_PATH"}, }, }, Action: func(cctx *cli.Context) error { diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index c8c650395..b7050febd 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -644,6 +644,7 @@ Response: { "Flags": 7, "Key": "string value", + "Codec": 42, "Value": "Ynl0ZSBhcnJheQ==" } ] @@ -2342,7 +2343,7 @@ Inputs: Response: ```json { - "oldestBlock": 42, + "oldestBlock": "0x5", "baseFeePerGas": [ "0x0" ], @@ -2407,7 +2408,7 @@ Response: "gasLimit": "0x5", "gasUsed": "0x5", "timestamp": "0x5", - "extraData": "Ynl0ZSBhcnJheQ==", + "extraData": "0x07", "mixHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", "nonce": "0x0707070707070707", "baseFeePerGas": "0x0", @@ -2451,7 +2452,7 @@ Response: "gasLimit": "0x5", "gasUsed": "0x5", "timestamp": "0x5", - "extraData": "Ynl0ZSBhcnJheQ==", + "extraData": "0x07", "mixHash": "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e", "nonce": "0x0707070707070707", "baseFeePerGas": "0x0", @@ -2643,7 +2644,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } @@ -2679,7 +2683,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } @@ -2714,7 +2721,10 @@ Response: "gas": "0x5", "maxFeePerGas": "0x0", "maxPriorityFeePerGas": "0x0", - "v": "0x0", + "accessList": [ + "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" + ], + "yParity": "0x0", "r": "0x0", "s": "0x0" } diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index 0c792ee1d..32df7d1f1 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit 0c792ee1d1f062377033d7d37442d18f765be467 +Subproject commit 32df7d1f15e46406c5efafb5de5c2c70ec34d685 diff --git a/gen/bundle/bundle.go b/gen/bundle/bundle.go index c7655157e..666ce9f66 100644 --- a/gen/bundle/bundle.go +++ b/gen/bundle/bundle.go @@ -20,6 +20,7 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet {{- range . }} { Network: {{printf "%q" .Network}}, Version: {{.Version}}, + {{if .BundleGitTag}} BundleGitTag: {{printf "%q" .BundleGitTag}}, {{end}} ManifestCid: MustParseCid({{printf "%q" .ManifestCid}}), Actors: map[string]cid.Cid { {{- range $name, $cid := .Actors }} @@ -37,6 +38,12 @@ func main() { panic(err) } + if len(os.Args) > 1 { + for _, m := range metadata { + m.BundleGitTag = os.Args[1] + } + } + fi, err := os.Create("./build/builtin_actors_gen.go") if err != nil { panic(err) diff --git a/go.mod b/go.mod index fa80158a7..f32f2f7ee 100644 --- a/go.mod +++ b/go.mod @@ -62,10 +62,12 @@ require ( github.com/gbrlsnchs/jwt/v3 v3.0.1 github.com/gdamore/tcell/v2 v2.2.0 github.com/go-kit/kit v0.12.0 + github.com/go-openapi/spec v0.19.11 github.com/golang/mock v1.6.0 github.com/google/uuid v1.3.0 github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 + github.com/gregdhill/go-openrpc v0.0.0-20220114144539-ae6f44720487 github.com/hako/durafmt v0.0.0-20200710122514-c0fb7b4da026 github.com/hannahhoward/go-pubsub v0.0.0-20200423002714-8d62886cc36e github.com/hashicorp/go-multierror v1.1.1 @@ -145,6 +147,7 @@ require ( github.com/whyrusleeping/cbor-gen v0.0.0-20221021053955-c138aae13722 github.com/whyrusleeping/ledger-filecoin-go v0.9.1-0.20201010031517-c3dcc1bddce4 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 + github.com/xeipuuv/gojsonschema v1.2.0 github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 go.opencensus.io v0.23.0 go.opentelemetry.io/otel v1.11.1 @@ -213,7 +216,6 @@ require ( github.com/go-ole/go-ole v1.2.5 // indirect github.com/go-openapi/jsonpointer v0.19.3 // indirect github.com/go-openapi/jsonreference v0.19.4 // indirect - github.com/go-openapi/spec v0.19.11 // indirect github.com/go-openapi/swag v0.19.11 // indirect github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect @@ -324,6 +326,8 @@ require ( github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee // indirect + github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f // indirect + github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/zondax/hid v0.9.1 // indirect github.com/zondax/ledger-go v0.12.1 // indirect diff --git a/go.sum b/go.sum index 50b00955f..c0fa2bbcb 100644 --- a/go.sum +++ b/go.sum @@ -451,6 +451,7 @@ github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwoh github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= github.com/go-openapi/jsonreference v0.19.4 h1:3Vw+rh13uq2JFNxgnMTGE1rnoieU9FmyE1gvnyylsYg= github.com/go-openapi/jsonreference v0.19.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/spec v0.19.2/go.mod h1:sCxk3jxKgioEJikev4fgkNmwS+3kuYdJtcsZsD5zxMY= github.com/go-openapi/spec v0.19.7/go.mod h1:Hm2Jr4jv8G1ciIAo+frC/Ft+rR2kQDh8JHKHb3gWUSk= github.com/go-openapi/spec v0.19.11 h1:ogU5q8dtp3MMPn59a9VRrPKVxvJHEs5P7yNMR5sNnis= github.com/go-openapi/spec v0.19.11/go.mod h1:vqK/dIdLGCosfvYsQV3WfC7N3TiZSnGY2RZKoFK7X28= @@ -464,6 +465,10 @@ github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/logger v1.0.0/go.mod h1:2zbswyIUa45I+c+FLXuWl9zSWEiVuthsk8ze5s8JvPs= +github.com/gobuffalo/packd v0.3.0/go.mod h1:zC7QkmNkYVGKPw4tHpBQ+ml7W/3tIebgeo1b36chA3Q= +github.com/gobuffalo/packr/v2 v2.6.0/go.mod h1:sgEE1xNZ6G0FNN5xn9pevVu4nywaxHvgup67xisti08= github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -586,6 +591,8 @@ github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gregdhill/go-openrpc v0.0.0-20220114144539-ae6f44720487 h1:NyaWOSkqFK1d9o+HLfnMIGzrHuUUPeBNIZyi5Zoe/lY= +github.com/gregdhill/go-openrpc v0.0.0-20220114144539-ae6f44720487/go.mod h1:a1eRkbhd3DYpRH2lnuUsVG+QMTI+v0hGnsis8C9hMrA= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= @@ -665,6 +672,7 @@ github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94 h1:9tcYMdi+7Rb1y0 github.com/icza/backscanner v0.0.0-20210726202459-ac2ffc679f94/go.mod h1:GYeBD1CF7AqnKZK+UCytLcY3G+UKo0ByXX/3xfdNyqQ= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6 h1:8UsGZ2rr2ksmEru6lToqnXgA8Mz1DP11X4zSJ159C3k= github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxdb1-client v0.0.0-20200827194710-b269163b24ab h1:HqW4xhhynfjrtEiiSGcQUd6vrK23iMam1FO8rI7mwig= @@ -923,6 +931,7 @@ github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9qUBdQ= @@ -951,6 +960,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= +github.com/karrick/godirwalk v1.10.12/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kilic/bls12-381 v0.0.0-20200607163746-32e1441c8a9f/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= @@ -976,6 +986,7 @@ github.com/klauspost/cpuid/v2 v2.1.1/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8t github.com/koalacxr/quantile v0.0.1 h1:wAW+SQ286Erny9wOjVww96t8ws+x5Zj6AKHDULUK+o0= github.com/koalacxr/quantile v0.0.1/go.mod h1:bGN/mCZLZ4lrSDHRQ6Lglj9chowGux8sGUIND+DQeD0= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= github.com/koron/go-ssdp v0.0.0-20191105050749-2e1c40ed0b5d/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= @@ -990,6 +1001,7 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -1693,6 +1705,7 @@ github.com/rivo/uniseg v0.1.0 h1:+2KBaVoUmb9XzDsrx/Ct0W/EYOSFf/nWTauy++DprtY= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= @@ -1779,6 +1792,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -1795,6 +1809,8 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/texttheater/golang-levenshtein v0.0.0-20180516184445-d188e65d659e/go.mod h1:XDKHRm5ThF8YJjx001LtgelzsoaEcvnA7lVWz9EeX3g= github.com/tidwall/gjson v1.6.0 h1:9VEQWz6LLMUsUl6PueE49ir4Ka6CzLymOAZDxpFsTDc= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= @@ -1880,6 +1896,12 @@ github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go. github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee h1:lYbXeSvJi5zk5GLKVuid9TVjS9a0OmLIDKTfoZBL6Ow= github.com/whyrusleeping/timecache v0.0.0-20160911033111-cfcb2f1abfee/go.mod h1:m2aV4LZI4Aez7dP5PMyVKEHhUyEJ/RjmPEDOpDvudHg= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xorcare/golden v0.6.0/go.mod h1:7T39/ZMvaSEZlBPoYfVFmsBLmUl3uz9IuzWj/U6FtvQ= github.com/xorcare/golden v0.6.1-0.20191112154924-b87f686d7542 h1:oWgZJmC1DorFZDpfMfWg7xk29yEOZiXmo/wZl+utTI8= @@ -2004,6 +2026,7 @@ golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190618222545-ea8f1a30c443/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190621222207-cc06ce4a13d4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190927123631-a832865fa7ad/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -2191,12 +2214,14 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190515120540-06a5c4944438/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190523142557-0e01d883c5c5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190524152521-dbbf3f1254d4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190526052359-791d8a0f4d09/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2308,6 +2333,7 @@ golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/itests/contracts/Create2Factory.hex b/itests/contracts/Create2Factory.hex new file mode 100644 index 000000000..006874306 --- /dev/null +++ b/itests/contracts/Create2Factory.hex @@ -0,0 +1 @@ +608060405234801561001057600080fd5b506109fb806100206000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80632b85ba3814610051578063732768dd146100815780637c3e4053146100b2578063bb29998e146100e2575b600080fd5b61006b60048036038101906100669190610473565b610112565b60405161007891906104e1565b60405180910390f35b61009b60048036038101906100969190610473565b61013f565b6040516100a9929190610517565b60405180910390f35b6100cc60048036038101906100c79190610473565b61027e565b6040516100d991906104e1565b60405180910390f35b6100fc60048036038101906100f7919061056c565b6102c0565b60405161010991906104e1565b60405180910390f35b6000816000819055506000806101278461013f565b915091508161013557600080fd5b8092505050919050565b60008060008360405160240161015591906105a8565b6040516020818303038152906040527f7c3e4053000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506000803073ffffffffffffffffffffffffffffffffffffffff16836040516101fc9190610634565b600060405180830381855af49150503d8060008114610237576040519150601f19603f3d011682016040523d82523d6000602084013e61023c565b606091505b5091509150811561026e5760008180602001905181019061025d9190610689565b905082819550955050505050610279565b816000945094505050505b915091565b6000818260405161028e9061042b565b61029891906105a8565b8190604051809103906000f59050801580156102b8573d6000803e3d6000fd5b509050919050565b6000808290508073ffffffffffffffffffffffffffffffffffffffff166383197ef06040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561030e57600080fd5b505af1158015610322573d6000803e3d6000fd5b5050505060008173ffffffffffffffffffffffffffffffffffffffff166367e404ce6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610373573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061039791906106cb565b905060006104128373ffffffffffffffffffffffffffffffffffffffff1663bfa0b1336040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103e9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061040d919061070d565b61013f565b509050801561042057600080fd5b819350505050919050565b61028b8061073b83390190565b600080fd5b6000819050919050565b6104508161043d565b811461045b57600080fd5b50565b60008135905061046d81610447565b92915050565b60006020828403121561048957610488610438565b5b60006104978482850161045e565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006104cb826104a0565b9050919050565b6104db816104c0565b82525050565b60006020820190506104f660008301846104d2565b92915050565b60008115159050919050565b610511816104fc565b82525050565b600060408201905061052c6000830185610508565b61053960208301846104d2565b9392505050565b610549816104c0565b811461055457600080fd5b50565b60008135905061056681610540565b92915050565b60006020828403121561058257610581610438565b5b600061059084828501610557565b91505092915050565b6105a28161043d565b82525050565b60006020820190506105bd6000830184610599565b92915050565b600081519050919050565b600081905092915050565b60005b838110156105f75780820151818401526020810190506105dc565b60008484015250505050565b600061060e826105c3565b61061881856105ce565b93506106288185602086016105d9565b80840191505092915050565b60006106408284610603565b915081905092915050565b6000610656826104a0565b9050919050565b6106668161064b565b811461067157600080fd5b50565b6000815190506106838161065d565b92915050565b60006020828403121561069f5761069e610438565b5b60006106ad84828501610674565b91505092915050565b6000815190506106c581610540565b92915050565b6000602082840312156106e1576106e0610438565b5b60006106ef848285016106b6565b91505092915050565b60008151905061070781610447565b92915050565b60006020828403121561072357610722610438565b5b6000610731848285016106f8565b9150509291505056fe608060405234801561001057600080fd5b5060405161028b38038061028b833981810160405281019061003291906100ba565b326000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600181905550506100e7565b600080fd5b6000819050919050565b61009781610084565b81146100a257600080fd5b50565b6000815190506100b48161008e565b92915050565b6000602082840312156100d0576100cf61007f565b5b60006100de848285016100a5565b91505092915050565b610195806100f66000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c806367e404ce1461004657806383197ef014610064578063bfa0b1331461006e575b600080fd5b61004e61008c565b60405161005b9190610110565b60405180910390f35b61006c6100b0565b005b6100766100c9565b6040516100839190610144565b60405180910390f35b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b3373ffffffffffffffffffffffffffffffffffffffff16ff5b60015481565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100fa826100cf565b9050919050565b61010a816100ef565b82525050565b60006020820190506101256000830184610101565b92915050565b6000819050919050565b61013e8161012b565b82525050565b60006020820190506101596000830184610135565b9291505056fea26469706673582212208252a57fdfc00b722b7063f2d28dd8c5a36b469462c89da52bcf17ccdda2de6764736f6c63430008110033a26469706673582212200edf974d1735ee81f671df7e60300ab28168b8cb22cc3e59180ef743c4a526c964736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/Create2Factory.sol b/itests/contracts/Create2Factory.sol new file mode 100644 index 000000000..ffec40822 --- /dev/null +++ b/itests/contracts/Create2Factory.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.17; +contract Create2Factory { + + bytes32 savedSalt; + + // Returns the address of the newly deployed contract + function deploy( + bytes32 _salt + ) public returns (address) { + // This syntax is a newer way to invoke create2 without assembly, you just need to pass salt + // https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2 + savedSalt = _salt; + (bool success, address ret) = deployDelegateCall(_salt); + require(success); + return ret; + } + + function deployDelegateCall( + bytes32 _salt + ) public returns (bool, address) { + bytes memory data = abi.encodeWithSignature("_deploy(bytes32)", _salt); + (bool success, bytes memory returnedData) = address(this).delegatecall(data); + if(success){ + (address ret) = abi.decode(returnedData, (address)); + return (success, ret); + }else{ + return (success, address(0)); + } + } + + function _deploy(bytes32 _salt) public returns (address) { + // https://solidity-by-example.org/app/create1/ + // This syntax is a newer way to invoke create2 without assembly, you just need to pass salt + // https://docs.soliditylang.org/en/latest/control-structures.html#salted-contract-creations-create2 + return address(new SelfDestruct{salt: _salt}(_salt)); + } + + function test(address _address) public returns (address){ + + // run destroy() on _address + SelfDestruct selfDestruct = SelfDestruct(_address); + selfDestruct.destroy(); + + //verify data can still be accessed + address ret = selfDestruct.sender(); + + // attempt and fail to deploy contract using salt + (bool success, ) = deployDelegateCall(selfDestruct.salt()); + require(!success); + + return ret; + } +} + +contract SelfDestruct { + address public sender; + bytes32 public salt; + constructor(bytes32 _salt) { + sender = tx.origin; + salt=_salt; + } + function destroy() public { + selfdestruct(payable(msg.sender)); + } +} + diff --git a/itests/contracts/DeployValueTest.hex b/itests/contracts/DeployValueTest.hex new file mode 100644 index 000000000..535704abf --- /dev/null +++ b/itests/contracts/DeployValueTest.hex @@ -0,0 +1 @@ +60806040523460405161001190610073565b6040518091039082f090508015801561002e573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061007f565b60c78061031683390190565b6102888061008e6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c80630e3608df146100465780634313b53114610064578063b0d22c6214610082575b600080fd5b61004e6100a0565b60405161005b919061017d565b60405180910390f35b61006c610137565b60405161007991906101d9565b60405180910390f35b61008a61015b565b604051610097919061017d565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166312065fe06040518163ffffffff1660e01b8152600401602060405180830381865afa15801561010e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101329190610225565b905090565b60008054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006007905090565b6000819050919050565b61017781610164565b82525050565b6000602082019050610192600083018461016e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006101c382610198565b9050919050565b6101d3816101b8565b82525050565b60006020820190506101ee60008301846101ca565b92915050565b600080fd5b61020281610164565b811461020d57600080fd5b50565b60008151905061021f816101f9565b92915050565b60006020828403121561023b5761023a6101f4565b5b600061024984828501610210565b9150509291505056fea2646970667358221220c24abd10dbe58d92bfe62cb351771fcdc45d54241a8ce7085f2a75179c67cd8a64736f6c63430008110033608060405260b5806100126000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806312065fe014602d575b600080fd5b60336047565b604051603e91906066565b60405180910390f35b600047905090565b6000819050919050565b606081604f565b82525050565b6000602082019050607960008301846059565b9291505056fea26469706673582212207123972a300833ee01aebf99e4bdf8ecf9f01c0d3dd776048bd41803c6855c0e64736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/DeployValueTest.sol b/itests/contracts/DeployValueTest.sol new file mode 100644 index 000000000..fe261b014 --- /dev/null +++ b/itests/contracts/DeployValueTest.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.17; + + + +contract DeployValueTest { + address public newContract; + + constructor() payable { + newContract = address(new NewContract{value: msg.value}()); + } + + function getConst() public view returns (uint) { + return 7; + } + + function getNewContractBalance() public view returns (uint) { + return NewContract(newContract).getBalance(); + } +} + +contract NewContract { + constructor() payable { + } + + function getBalance() public view returns (uint) { + return address(this).balance; + } +} diff --git a/itests/contracts/compile.sh b/itests/contracts/compile.sh old mode 100755 new mode 100644 index 4395fdb53..029bff46c --- a/itests/contracts/compile.sh +++ b/itests/contracts/compile.sh @@ -12,7 +12,7 @@ find . -name \*.sol -print0 | #for these contracts we have 2 contracts in the same solidity file #this command grabs the correct bytecode for us -for filename in Constructor TestApp ValueSender ; do +for filename in Constructor TestApp ValueSender Create2Factory DeployValueTest; do echo $filename solc --bin $filename.sol | tail -n5|head -n1 | tr -d "\n" > $filename.hex done diff --git a/itests/decode_params_test.go b/itests/decode_params_test.go new file mode 100644 index 000000000..6a4a8c681 --- /dev/null +++ b/itests/decode_params_test.go @@ -0,0 +1,124 @@ +// stm: #integration +package itests + +import ( + "bytes" + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/builtin" + "github.com/filecoin-project/go-state-types/builtin/v10/eam" + "github.com/filecoin-project/go-state-types/cbor" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/cli" +) + +type marshalable interface { + cbor.Marshaler + cbor.Unmarshaler +} + +type testCase struct { + ActorKey string + MethodNum abi.MethodNum + retVal marshalable +} + +// Used './lotus state replay --show-trace ' to get params/return to decode. +func TestDecodeParams(t *testing.T) { + testCborBytes := abi.CborBytes([]byte{1, 2, 3}) + + testCases := []testCase{ + { + ActorKey: manifest.EvmKey, + MethodNum: builtin.MethodsEVM.InvokeContract, + retVal: &testCborBytes, + }, + { + ActorKey: manifest.EamKey, + MethodNum: builtin.MethodsEAM.CreateExternal, + retVal: &testCborBytes, + }, + } + + for _, _tc := range testCases { + tc := _tc + t.Run(tc.ActorKey+" "+tc.MethodNum.String(), func(t *testing.T) { + av, err := actorstypes.VersionForNetwork(build.TestNetworkVersion) + require.NoError(t, err) + actorCodeCid, found := actors.GetActorCodeID(av, tc.ActorKey) + require.True(t, found) + + buf := bytes.NewBuffer(nil) + if err := tc.retVal.MarshalCBOR(buf); err != nil { + t.Fatal(err) + } + + paramString, err := cli.JsonParams(actorCodeCid, tc.MethodNum, buf.Bytes()) + require.NoError(t, err) + + jsonParams, err := json.MarshalIndent(tc.retVal, "", " ") + require.NoError(t, err) + require.Equal(t, string(jsonParams), paramString) + }) + } +} + +func TestDecodeReturn(t *testing.T) { + testCborBytes := abi.CborBytes([]byte{1, 2, 3}) + + robustAddr, err := address.NewIDAddress(12345) + require.NoError(t, err) + + //ethAddr, err := ethtypes.ParseEthAddress("d4c5fb16488Aa48081296299d54b0c648C9333dA") + //require.NoError(t, err) + + testReturn := eam.CreateExternalReturn{ + ActorID: 12345, + RobustAddress: &robustAddr, + EthAddress: [20]byte{}, + } + + testCases := []testCase{ + { + ActorKey: manifest.EvmKey, + MethodNum: builtin.MethodsEVM.InvokeContract, + retVal: &testCborBytes, + }, + { + ActorKey: manifest.EamKey, + MethodNum: builtin.MethodsEAM.CreateExternal, + retVal: &testReturn, + }, + } + + for _, _tc := range testCases { + tc := _tc + t.Run(tc.ActorKey+" "+tc.MethodNum.String(), func(t *testing.T) { + av, err := actorstypes.VersionForNetwork(build.TestNetworkVersion) + require.NoError(t, err) + actorCodeCid, found := actors.GetActorCodeID(av, tc.ActorKey) + require.True(t, found) + + buf := bytes.NewBuffer(nil) + if err := tc.retVal.MarshalCBOR(buf); err != nil { + t.Fatal(err) + } + + returnString, err := cli.JsonReturn(actorCodeCid, tc.MethodNum, buf.Bytes()) + require.NoError(t, err) + + jsonReturn, err := json.MarshalIndent(tc.retVal, "", " ") + require.NoError(t, err) + require.Equal(t, string(jsonReturn), returnString) + }) + } +} diff --git a/itests/eth_conformance_test.go b/itests/eth_conformance_test.go new file mode 100644 index 000000000..c190e03fe --- /dev/null +++ b/itests/eth_conformance_test.go @@ -0,0 +1,514 @@ +package itests + +import ( + "bytes" + "context" + "encoding/binary" + "encoding/hex" + "encoding/json" + "os" + "strings" + "testing" + "time" + + "github.com/go-openapi/spec" + "github.com/gregdhill/go-openrpc/parse" + orpctypes "github.com/gregdhill/go-openrpc/types" + manet "github.com/multiformats/go-multiaddr/net" + "github.com/stretchr/testify/require" + "github.com/xeipuuv/gojsonschema" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-jsonrpc" + "github.com/filecoin-project/go-state-types/big" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" + "github.com/filecoin-project/lotus/chain/wallet/key" + "github.com/filecoin-project/lotus/itests/kit" +) + +// TODO generate this using reflection. It's the same as the EthAPI except every return value is a json.RawMessage +type ethAPIRaw struct { + EthAccounts func(context.Context) (json.RawMessage, error) + EthBlockNumber func(context.Context) (json.RawMessage, error) + EthCall func(context.Context, ethtypes.EthCall, string) (json.RawMessage, error) + EthChainId func(context.Context) (json.RawMessage, error) + EthEstimateGas func(context.Context, ethtypes.EthCall) (json.RawMessage, error) + EthFeeHistory func(context.Context, ethtypes.EthUint64, string, []float64) (json.RawMessage, error) + EthGasPrice func(context.Context) (json.RawMessage, error) + EthGetBalance func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) + EthGetBlockByHash func(context.Context, ethtypes.EthHash, bool) (json.RawMessage, error) + EthGetBlockByNumber func(context.Context, string, bool) (json.RawMessage, error) + EthGetBlockTransactionCountByHash func(context.Context, ethtypes.EthHash) (json.RawMessage, error) + EthGetBlockTransactionCountByNumber func(context.Context, ethtypes.EthUint64) (json.RawMessage, error) + EthGetCode func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) + EthGetFilterChanges func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error) + EthGetFilterLogs func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error) + EthGetLogs func(context.Context, *ethtypes.EthFilterSpec) (json.RawMessage, error) + EthGetStorageAt func(context.Context, ethtypes.EthAddress, ethtypes.EthBytes, string) (json.RawMessage, error) + EthGetTransactionByBlockHashAndIndex func(context.Context, ethtypes.EthHash, ethtypes.EthUint64) (json.RawMessage, error) + EthGetTransactionByBlockNumberAndIndex func(context.Context, ethtypes.EthUint64, ethtypes.EthUint64) (json.RawMessage, error) + EthGetTransactionByHash func(context.Context, *ethtypes.EthHash) (json.RawMessage, error) + EthGetTransactionCount func(context.Context, ethtypes.EthAddress, string) (json.RawMessage, error) + EthGetTransactionReceipt func(context.Context, ethtypes.EthHash) (json.RawMessage, error) + EthMaxPriorityFeePerGas func(context.Context) (json.RawMessage, error) + EthNewBlockFilter func(context.Context) (json.RawMessage, error) + EthNewFilter func(context.Context, *ethtypes.EthFilterSpec) (json.RawMessage, error) + EthNewPendingTransactionFilter func(context.Context) (json.RawMessage, error) + EthSendRawTransaction func(context.Context, ethtypes.EthBytes) (json.RawMessage, error) + EthSubscribe func(context.Context, string, *ethtypes.EthSubscriptionParams) (json.RawMessage, error) + EthUninstallFilter func(context.Context, ethtypes.EthFilterID) (json.RawMessage, error) + EthUnsubscribe func(context.Context, ethtypes.EthSubscriptionID) (json.RawMessage, error) +} + +func TestEthOpenRPCConformance(t *testing.T) { + kit.QuietAllLogsExcept("events", "messagepool") + + // specs/eth_openrpc.json is built from https://github.com/ethereum/execution-apis + specJSON, err := os.ReadFile("specs/eth_openrpc.json") + require.NoError(t, err) + + specParsed := orpctypes.NewOpenRPCSpec1() + err = json.Unmarshal(specJSON, specParsed) + require.NoError(t, err) + parse.GetTypes(specParsed, specParsed.Objects) + + schemas := make(map[string]spec.Schema) + for _, method := range specParsed.Methods { + if method.Result != nil { + schemas[method.Name] = method.Result.Schema + } + } + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC(), kit.WithEthRPC()) + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + contractHex, err := os.ReadFile("contracts/EventMatrix.hex") + require.NoError(t, err) + + // strip any trailing newlines from the file + contractHex = bytes.TrimRight(contractHex, "\n") + + contractBin, err := hex.DecodeString(string(contractHex)) + require.NoError(t, err) + + senderKey, senderEthAddr, senderFilAddr := client.EVM().NewAccount() + _, receiverEthAddr, _ := client.EVM().NewAccount() + kit.SendFunds(ctx, t, client, senderFilAddr, types.FromFil(1000)) + + deployerAddr, err := client.EVM().WalletDefaultAddress(ctx) + require.NoError(t, err) + + pendingTransactionFilterID, err := client.EthNewPendingTransactionFilter(ctx) + require.NoError(t, err) + + blockFilterID, err := client.EthNewBlockFilter(ctx) + require.NoError(t, err) + + filterAllLogs := kit.NewEthFilterBuilder().FromBlockEpoch(0).Filter() + + logFilterID, err := client.EthNewFilter(ctx, filterAllLogs) + require.NoError(t, err) + + uninstallableFilterID, err := client.EthNewFilter(ctx, filterAllLogs) + require.NoError(t, err) + + rawSignedEthTx := createRawSignedEthTx(ctx, t, client, senderEthAddr, receiverEthAddr, senderKey, contractBin) + + result := client.EVM().DeployContract(ctx, deployerAddr, contractBin) + contractAddr, err := address.NewIDAddress(result.ActorID) + require.NoError(t, err) + + contractEthAddr := ethtypes.EthAddress(result.EthAddress) + + messageWithEvents, blockHashWithMessage, blockNumberWithMessage := waitForMessageWithEvents(ctx, t, client, deployerAddr, contractAddr) + + // create a json-rpc client that returns raw json responses + var ethapi ethAPIRaw + + netAddr, err := manet.ToNetAddr(client.ListenAddr) + require.NoError(t, err) + rpcAddr := "ws://" + netAddr.String() + "/rpc/v1" + + closer, err := jsonrpc.NewClient(ctx, rpcAddr, "Filecoin", ðapi, nil) + require.NoError(t, err) + defer closer() + + testCases := []struct { + method string + variant string // suffix applied to the test name to distinguish different variants of a method call + call func(*ethAPIRaw) (json.RawMessage, error) + skipReason string + }{ + // Alphabetical order + + { + method: "eth_accounts", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthAccounts(context.Background()) + }, + }, + + { + method: "eth_blockNumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthBlockNumber(context.Background()) + }, + }, + + { + method: "eth_call", + variant: "latest", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthCall(context.Background(), ethtypes.EthCall{ + From: &senderEthAddr, + Data: contractBin, + }, "latest") + }, + }, + + { + method: "eth_chainId", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthChainId(context.Background()) + }, + }, + + { + method: "eth_estimateGas", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthEstimateGas(context.Background(), ethtypes.EthCall{ + From: &senderEthAddr, + Data: contractBin, + }) + }, + }, + + { + method: "eth_feeHistory", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthFeeHistory(context.Background(), ethtypes.EthUint64(2), "", nil) + }, + }, + + { + method: "eth_gasPrice", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGasPrice(context.Background()) + }, + }, + + { + method: "eth_getBalance", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBalance(context.Background(), contractEthAddr, "0x0") + }, + }, + + { + method: "eth_getBlockByHash", + variant: "txhashes", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockByHash(context.Background(), blockHashWithMessage, false) + }, + }, + + { + method: "eth_getBlockByHash", + variant: "txfull", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockByHash(context.Background(), blockHashWithMessage, true) + }, + }, + + { + method: "eth_getBlockByNumber", + variant: "earliest", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockByNumber(context.Background(), "earliest", true) + }, + skipReason: "earliest block is not supported", + }, + + { + method: "eth_getBlockByNumber", + variant: "pending", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockByNumber(context.Background(), "pending", true) + }, + }, + + { + method: "eth_getBlockByNumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockByNumber(context.Background(), blockNumberWithMessage.Hex(), true) + }, + }, + + { + method: "eth_getBlockTransactionCountByHash", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockTransactionCountByHash(context.Background(), blockHashWithMessage) + }, + }, + + { + method: "eth_getBlockTransactionCountByNumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetBlockTransactionCountByNumber(context.Background(), blockNumberWithMessage) + }, + }, + + { + method: "eth_getCode", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetCode(context.Background(), contractEthAddr, blockNumberWithMessage.Hex()) + }, + }, + + { + method: "eth_getFilterChanges", + variant: "pendingtransaction", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return a.EthGetFilterChanges(ctx, pendingTransactionFilterID) + }, + }, + + { + method: "eth_getFilterChanges", + variant: "block", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return a.EthGetFilterChanges(ctx, blockFilterID) + }, + }, + + { + method: "eth_getFilterChanges", + variant: "logs", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return a.EthGetFilterChanges(ctx, logFilterID) + }, + }, + + { + method: "eth_getFilterLogs", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return a.EthGetFilterLogs(ctx, logFilterID) + }, + }, + + { + method: "eth_getLogs", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetLogs(context.Background(), filterAllLogs) + }, + }, + + { + method: "eth_getStorageAt", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetStorageAt(context.Background(), contractEthAddr, ethtypes.EthBytes{0}, "0x0") + }, + }, + + { + method: "eth_getTransactionByBlockHashAndIndex", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionByBlockHashAndIndex(context.Background(), blockHashWithMessage, ethtypes.EthUint64(0)) + }, + skipReason: "unimplemented", + }, + + { + method: "eth_getTransactionByBlockNumberAndIndex", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionByBlockNumberAndIndex(context.Background(), blockNumberWithMessage, ethtypes.EthUint64(0)) + }, + skipReason: "unimplemented", + }, + + { + method: "eth_getTransactionByHash", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionByHash(context.Background(), &messageWithEvents) + }, + }, + + { + method: "eth_getTransactionCount", + variant: "blocknumber", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionCount(context.Background(), senderEthAddr, blockNumberWithMessage.Hex()) + }, + }, + + { + method: "eth_getTransactionReceipt", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthGetTransactionReceipt(context.Background(), messageWithEvents) + }, + }, + + { + method: "eth_maxPriorityFeePerGas", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthMaxPriorityFeePerGas(context.Background()) + }, + }, + + { + method: "eth_newBlockFilter", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthNewBlockFilter(context.Background()) + }, + }, + + { + method: "eth_newFilter", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthNewFilter(context.Background(), filterAllLogs) + }, + }, + + { + method: "eth_newPendingTransactionFilter", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthNewPendingTransactionFilter(context.Background()) + }, + }, + + { + method: "eth_sendRawTransaction", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return ethapi.EthSendRawTransaction(context.Background(), rawSignedEthTx) + }, + }, + { + method: "eth_uninstallFilter", + call: func(a *ethAPIRaw) (json.RawMessage, error) { + return a.EthUninstallFilter(ctx, uninstallableFilterID) + }, + }, + } + + for _, tc := range testCases { + tc := tc + name := tc.method + if tc.variant != "" { + name += "_" + tc.variant + } + t.Run(name, func(t *testing.T) { + if tc.skipReason != "" { + t.Skipf(tc.skipReason) + } + + schema, ok := schemas[tc.method] + require.True(t, ok, "method not found in openrpc spec") + + resp, err := tc.call(ðapi) + require.NoError(t, err) + + respJson, err := json.Marshal(resp) + require.NoError(t, err) + + loader := gojsonschema.NewGoLoader(schema) + resploader := gojsonschema.NewBytesLoader(respJson) + result, err := gojsonschema.Validate(loader, resploader) + require.NoError(t, err) + + if !result.Valid() { + if len(result.Errors()) == 1 && strings.Contains(result.Errors()[0].String(), "Must validate one and only one schema (oneOf)") { + // Ignore this error, since it seems the openrpc spec can't handle it + // New transaction and block filters have the same schema: an array of 32 byte hashes + return + } + + niceRespJson, err := json.MarshalIndent(resp, "", " ") + if err == nil { + t.Logf("response was %s", niceRespJson) + } + + schemaJson, err := json.MarshalIndent(schema, "", " ") + if err == nil { + t.Logf("schema was %s", schemaJson) + } + + // check against https://www.jsonschemavalidator.net/ + + for _, desc := range result.Errors() { + t.Logf("- %s\n", desc) + } + + t.Errorf("response did not validate") + } + }) + } +} + +func createRawSignedEthTx(ctx context.Context, t *testing.T, client *kit.TestFullNode, senderEthAddr ethtypes.EthAddress, receiverEthAddr ethtypes.EthAddress, senderKey *key.Key, contractBin []byte) []byte { + gaslimit, err := client.EthEstimateGas(ctx, ethtypes.EthCall{ + From: &senderEthAddr, + Data: contractBin, + }) + require.NoError(t, err) + + maxPriorityFeePerGas, err := client.EthMaxPriorityFeePerGas(ctx) + require.NoError(t, err) + + tx := ethtypes.EthTxArgs{ + ChainID: build.Eip155ChainId, + Value: big.NewInt(100), + Nonce: 0, + To: &receiverEthAddr, + MaxFeePerGas: types.NanoFil, + MaxPriorityFeePerGas: big.Int(maxPriorityFeePerGas), + GasLimit: int(gaslimit), + V: big.Zero(), + R: big.Zero(), + S: big.Zero(), + } + + client.EVM().SignTransaction(&tx, senderKey.PrivateKey) + signed, err := tx.ToRlpSignedMsg() + require.NoError(t, err) + return signed +} + +func waitForMessageWithEvents(ctx context.Context, t *testing.T, client *kit.TestFullNode, sender address.Address, target address.Address) (ethtypes.EthHash, ethtypes.EthHash, ethtypes.EthUint64) { + vals := []uint64{44, 27, 19, 12} + inputData := []byte{} + for _, v := range vals { + buf := make([]byte, 32) + binary.BigEndian.PutUint64(buf[24:], v) + inputData = append(inputData, buf...) + } + + // send a message that exercises event logs + ret, err := client.EVM().InvokeSolidity(ctx, sender, target, kit.EventMatrixContract.Fn["logEventThreeIndexedWithData"], inputData) + require.NoError(t, err) + require.True(t, ret.Receipt.ExitCode.IsSuccess(), "contract execution failed") + + msgHash, err := client.EthGetTransactionHashByCid(ctx, ret.Message) + require.NoError(t, err) + require.NotNil(t, msgHash) + + ts, err := client.ChainGetTipSet(ctx, ret.TipSet) + require.NoError(t, err) + + blockNumber := ethtypes.EthUint64(ts.Height()) + + tsCid, err := ts.Key().Cid() + require.NoError(t, err) + + blockHash, err := ethtypes.EthHashFromCid(tsCid) + require.NoError(t, err) + return *msgHash, blockHash, blockNumber +} diff --git a/itests/eth_deploy_test.go b/itests/eth_deploy_test.go index 98038de7b..bbdadb1d5 100644 --- a/itests/eth_deploy_test.go +++ b/itests/eth_deploy_test.go @@ -11,12 +11,16 @@ import ( "time" "github.com/stretchr/testify/require" + "golang.org/x/crypto/sha3" "github.com/filecoin-project/go-state-types/big" "github.com/filecoin-project/go-state-types/manifest" + gstStore "github.com/filecoin-project/go-state-types/store" "github.com/filecoin-project/lotus/api" + "github.com/filecoin-project/lotus/blockstore" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/actors/builtin/evm" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" "github.com/filecoin-project/lotus/itests/kit" @@ -219,4 +223,32 @@ func TestDeployment(t *testing.T) { require.NoError(t, err) client.AssertActorType(ctx, contractAddr, "evm") + + // Check bytecode and bytecode hash match. + contractAct, err := client.StateGetActor(ctx, contractAddr, types.EmptyTSK) + require.NoError(t, err) + + bs := blockstore.NewAPIBlockstore(client) + ctxStore := gstStore.WrapBlockStore(ctx, bs) + + evmSt, err := evm.Load(ctxStore, contractAct) + require.NoError(t, err) + + byteCodeCid, err := evmSt.GetBytecodeCID() + require.NoError(t, err) + + byteCode, err := bs.Get(ctx, byteCodeCid) + require.NoError(t, err) + + byteCodeHashChain, err := evmSt.GetBytecodeHash() + require.NoError(t, err) + + hasher := sha3.NewLegacyKeccak256() + hasher.Write(byteCode.RawData()) + byteCodeHash := hasher.Sum(nil) + require.Equal(t, byteCodeHashChain[:], byteCodeHash) + + byteCodeSt, err := evmSt.GetBytecode() + require.NoError(t, err) + require.Equal(t, byteCode.RawData(), byteCodeSt) } diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index d26222e69..59e0e6337 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -1,4 +1,3 @@ -// stm: #integration package itests import ( @@ -8,6 +7,7 @@ import ( "encoding/hex" "encoding/json" "fmt" + "math/bits" "os" "sort" "strconv" @@ -17,8 +17,6 @@ import ( "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" - cbg "github.com/whyrusleeping/cbor-gen" - "golang.org/x/crypto/sha3" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -34,53 +32,6 @@ import ( res "github.com/filecoin-project/lotus/lib/result" ) -// SolidityContractDef holds information about one of the test contracts -type SolidityContractDef struct { - Filename string // filename of the hex of the contract, e.g. contracts/EventMatrix.hex - Fn map[string][]byte // mapping of function names to 32-bit selector - Ev map[string][]byte // mapping of event names to 256-bit signature hashes -} - -var EventMatrixContract = SolidityContractDef{ - Filename: "contracts/EventMatrix.hex", - Fn: map[string][]byte{ - "logEventZeroData": ethFunctionHash("logEventZeroData()"), - "logEventOneData": ethFunctionHash("logEventOneData(uint256)"), - "logEventTwoData": ethFunctionHash("logEventTwoData(uint256,uint256)"), - "logEventThreeData": ethFunctionHash("logEventThreeData(uint256,uint256,uint256)"), - "logEventFourData": ethFunctionHash("logEventFourData(uint256,uint256,uint256,uint256)"), - "logEventOneIndexed": ethFunctionHash("logEventOneIndexed(uint256)"), - "logEventTwoIndexed": ethFunctionHash("logEventTwoIndexed(uint256,uint256)"), - "logEventThreeIndexed": ethFunctionHash("logEventThreeIndexed(uint256,uint256,uint256)"), - "logEventOneIndexedWithData": ethFunctionHash("logEventOneIndexedWithData(uint256,uint256)"), - "logEventTwoIndexedWithData": ethFunctionHash("logEventTwoIndexedWithData(uint256,uint256,uint256)"), - "logEventThreeIndexedWithData": ethFunctionHash("logEventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), - }, - Ev: map[string][]byte{ - "EventZeroData": ethTopicHash("EventZeroData()"), - "EventOneData": ethTopicHash("EventOneData(uint256)"), - "EventTwoData": ethTopicHash("EventTwoData(uint256,uint256)"), - "EventThreeData": ethTopicHash("EventThreeData(uint256,uint256,uint256)"), - "EventFourData": ethTopicHash("EventFourData(uint256,uint256,uint256,uint256)"), - "EventOneIndexed": ethTopicHash("EventOneIndexed(uint256)"), - "EventTwoIndexed": ethTopicHash("EventTwoIndexed(uint256,uint256)"), - "EventThreeIndexed": ethTopicHash("EventThreeIndexed(uint256,uint256,uint256)"), - "EventOneIndexedWithData": ethTopicHash("EventOneIndexedWithData(uint256,uint256)"), - "EventTwoIndexedWithData": ethTopicHash("EventTwoIndexedWithData(uint256,uint256,uint256)"), - "EventThreeIndexedWithData": ethTopicHash("EventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), - }, -} - -var EventsContract = SolidityContractDef{ - Filename: "contracts/events.bin", - Fn: map[string][]byte{ - "log_zero_data": {0x00, 0x00, 0x00, 0x00}, - "log_zero_nodata": {0x00, 0x00, 0x00, 0x01}, - "log_four_data": {0x00, 0x00, 0x00, 0x02}, - }, - Ev: map[string][]byte{}, -} - func TestEthNewPendingTransactionFilter(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() @@ -340,7 +291,7 @@ func TestEthNewFilterDefaultSpec(t *testing.T) { paddedEthBytes([]byte{0x33, 0x33}), paddedEthBytes([]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, @@ -350,7 +301,7 @@ func TestEthNewFilterDefaultSpec(t *testing.T) { paddedEthBytes([]byte{0x33, 0x33}), paddedEthBytes([]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, @@ -360,7 +311,7 @@ func TestEthNewFilterDefaultSpec(t *testing.T) { paddedEthBytes([]byte{0x33, 0x33}), paddedEthBytes([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, } @@ -385,7 +336,7 @@ func TestEthGetLogsBasic(t *testing.T) { ethContractAddr, received := invokeLogFourData(t, client, invocations) // Build filter spec - spec := newEthFilterBuilder(). + spec := kit.NewEthFilterBuilder(). FromBlockEpoch(0). Topic1OneOf(paddedEthHash([]byte{0x11, 0x11})). Filter() @@ -399,7 +350,7 @@ func TestEthGetLogsBasic(t *testing.T) { paddedEthBytes([]byte{0x33, 0x33}), paddedEthBytes([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, }, } @@ -464,7 +415,7 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { paddedEthBytes([]byte{0x33, 0x33}), paddedEthBytes([]byte{0x44, 0x44}), }, - Data: paddedEthBytes([]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}), + Data: []byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, } } @@ -473,6 +424,51 @@ func TestEthSubscribeLogsNoTopicSpec(t *testing.T) { AssertEthLogs(t, elogs, expected, messages) } +func TestTxReceiptBloom(t *testing.T) { + blockTime := 50 * time.Millisecond + client, _, ens := kit.EnsembleMinimal( + t, + kit.MockProofs(), + kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blockTime) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, "contracts/EventMatrix.hex") + + _, ml, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "logEventZeroData()", nil) + require.NoError(t, err) + + th, err := client.EthGetTransactionHashByCid(ctx, ml.Message) + require.NoError(t, err) + require.NotNil(t, th) + + receipt, err := client.EthGetTransactionReceipt(ctx, *th) + require.NoError(t, err) + require.NotNil(t, receipt) + require.Len(t, receipt.Logs, 1) + + // computed by calling EventMatrix/logEventZeroData in remix + // note this only contains topic bits + matchMask := "0x00000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + + maskBytes, err := hex.DecodeString(matchMask[2:]) + require.NoError(t, err) + + bitsSet := 0 + for i, maskByte := range maskBytes { + bitsSet += bits.OnesCount8(receipt.LogsBloom[i]) + + if maskByte > 0 { + require.True(t, maskByte&receipt.LogsBloom[i] > 0) + } + } + + // 3 bits from the topic, 3 bits from the address + require.Equal(t, 6, bitsSet) +} + func TestEthGetLogs(t *testing.T) { require := require.New(t) kit.QuietAllLogsExcept("events", "messagepool") @@ -612,19 +608,13 @@ func TestEthSubscribeLogs(t *testing.T) { var elogs []*ethtypes.EthLog for resp := range responseCh { - rlist, ok := resp.Result.([]interface{}) - require.True(ok, "expected subscription result to be []interface{}, but was %T", resp.Result) + rmap, ok := resp.Result.(map[string]interface{}) + require.True(ok, "expected subscription result entry to be map[string]interface{}, but was %T", resp.Result) - for _, rentry := range rlist { - rmap, ok := rentry.(map[string]interface{}) - require.True(ok, "expected subscription result entry to be map[string]interface{}, but was %T", resp.Result) - - elog, err := ParseEthLog(rmap) - require.NoError(err) - - elogs = append(elogs, elog) - } + elog, err := ParseEthLog(rmap) + require.NoError(err) + elogs = append(elogs, elog) } AssertEthLogs(t, elogs, tc.expected, messages) }) @@ -698,8 +688,8 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { // Select events for partitioning for _, m := range messages { - if bytes.Equal(m.invocation.Selector, EventMatrixContract.Fn["logEventTwoIndexedWithData"]) { - addr := getContractEthAddress(ctx, t, client, m.invocation.Target) + if bytes.Equal(m.invocation.Selector, kit.EventMatrixContract.Fn["logEventTwoIndexedWithData"]) { + addr := getEthAddress(ctx, t, client, m.invocation.Target) args := unpackUint64Values(m.invocation.Data) require.Equal(3, len(args), "logEventTwoIndexedWithData should have 3 arguments") @@ -707,7 +697,7 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { expectedByHeight[m.ts.Height()] = append(expectedByHeight[m.ts.Height()], ExpectedEthLog{ Address: addr, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(args[0]), paddedUint64(args[1]), }, @@ -772,7 +762,7 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { require.True(len(partition3.expected) > 0, "partition should have events") // these are the topics we selected for partitioning earlier - topics := []ethtypes.EthHash{paddedEthHash(EventMatrixContract.Ev["EventTwoIndexedWithData"])} + topics := []ethtypes.EthHash{paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])} union := func(lists ...[]ExpectedEthLog) []ExpectedEthLog { ret := []ExpectedEthLog{} @@ -789,91 +779,91 @@ func TestEthGetLogsWithBlockRanges(t *testing.T) { }{ { name: "find all events from genesis", - spec: newEthFilterBuilder().FromBlockEpoch(0).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(0).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected, partition2.expected, partition3.expected), }, { name: "find all from start of partition1", - spec: newEthFilterBuilder().FromBlockEpoch(partition1.start).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition1.start).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected, partition2.expected, partition3.expected), }, { name: "find all from start of partition2", - spec: newEthFilterBuilder().FromBlockEpoch(partition2.start).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition2.start).Topic1OneOf(topics...).Filter(), expected: union(partition2.expected, partition3.expected), }, { name: "find all from start of partition3", - spec: newEthFilterBuilder().FromBlockEpoch(partition3.start).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition3.start).Topic1OneOf(topics...).Filter(), expected: union(partition3.expected), }, { name: "find none after end of partition3", - spec: newEthFilterBuilder().FromBlockEpoch(partition3.end + 1).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition3.end + 1).Topic1OneOf(topics...).Filter(), expected: nil, }, { name: "find all events from genesis to end of partition1", - spec: newEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected), }, { name: "find all events from genesis to end of partition2", - spec: newEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition2.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition2.end).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected, partition2.expected), }, { name: "find all events from genesis to end of partition3", - spec: newEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition3.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition3.end).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected, partition2.expected, partition3.expected), }, { name: "find none from genesis to start of partition1", - spec: newEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition1.start - 1).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(0).ToBlockEpoch(partition1.start - 1).Topic1OneOf(topics...).Filter(), expected: nil, }, { name: "find all events in partition1", - spec: newEthFilterBuilder().FromBlockEpoch(partition1.start).ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition1.start).ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected), }, { name: "find all events in partition2", - spec: newEthFilterBuilder().FromBlockEpoch(partition2.start).ToBlockEpoch(partition2.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition2.start).ToBlockEpoch(partition2.end).Topic1OneOf(topics...).Filter(), expected: union(partition2.expected), }, { name: "find all events in partition3", - spec: newEthFilterBuilder().FromBlockEpoch(partition3.start).ToBlockEpoch(partition3.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition3.start).ToBlockEpoch(partition3.end).Topic1OneOf(topics...).Filter(), expected: union(partition3.expected), }, { name: "find all events from earliest to end of partition1", - spec: newEthFilterBuilder().FromBlock("earliest").ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock("earliest").ToBlockEpoch(partition1.end).Topic1OneOf(topics...).Filter(), expected: union(partition1.expected), }, { name: "find all events from start of partition3 to latest", - spec: newEthFilterBuilder().FromBlockEpoch(partition3.start).ToBlock("latest").Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlockEpoch(partition3.start).ToBlock("latest").Topic1OneOf(topics...).Filter(), expected: union(partition3.expected), }, { name: "find all events from earliest to latest", - spec: newEthFilterBuilder().FromBlock("earliest").ToBlock("latest").Topic1OneOf(topics...).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock("earliest").ToBlock("latest").Topic1OneOf(topics...).Filter(), expected: union(partition1.expected, partition2.expected, partition3.expected), }, } @@ -903,20 +893,20 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - sender, contract := client.EVM().DeployContractFromFilename(ctx, EventMatrixContract.Filename) + sender, contract := client.EVM().DeployContractFromFilename(ctx, kit.EventMatrixContract.Filename) // generate some events before the creation of the filter preInvocations := []Invocation{ { Sender: sender, Target: contract, - Selector: EventMatrixContract.Fn["logEventOneData"], + Selector: kit.EventMatrixContract.Fn["logEventOneData"], Data: packUint64Values(1), }, { Sender: sender, Target: contract, - Selector: EventMatrixContract.Fn["logEventOneIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexed"], Data: packUint64Values(2), }, } @@ -924,7 +914,7 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) { messages := invokeAndWaitUntilAllOnChain(t, client, preInvocations) // now install filter - spec := newEthFilterBuilder().FromBlock("earliest").Filter() + spec := kit.NewEthFilterBuilder().FromBlock("earliest").Filter() filterID, err := client.EthNewFilter(ctx, spec) require.NoError(err) @@ -934,13 +924,13 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) { { Sender: sender, Target: contract, - Selector: EventMatrixContract.Fn["logEventOneData"], + Selector: kit.EventMatrixContract.Fn["logEventOneData"], Data: packUint64Values(3), }, { Sender: sender, Target: contract, - Selector: EventMatrixContract.Fn["logEventOneIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexed"], Data: packUint64Values(4), }, } @@ -954,35 +944,35 @@ func TestEthNewFilterMergesHistoricWithRealtime(t *testing.T) { res, err := client.EthGetFilterChanges(ctx, filterID) require.NoError(err) - ethContractAddr := getContractEthAddress(ctx, t, client, contract) + ethContractAddr := getEthAddress(ctx, t, client, contract) // expect to see 2 messages from before the filter was installed and 2 after expected := []ExpectedEthLog{ { Address: ethContractAddr, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneData"], + kit.EventMatrixContract.Ev["EventOneData"], }, Data: paddedUint64(1), }, { Address: ethContractAddr, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexed"], + kit.EventMatrixContract.Ev["EventOneIndexed"], paddedUint64(2), }, }, { Address: ethContractAddr, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneData"], + kit.EventMatrixContract.Ev["EventOneData"], }, Data: paddedUint64(3), }, { Address: ethContractAddr, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexed"], + kit.EventMatrixContract.Ev["EventOneIndexed"], paddedUint64(4), }, }, @@ -1005,7 +995,7 @@ type msgInTipset struct { reverted bool } -func getContractEthAddress(ctx context.Context, t *testing.T, client *kit.TestFullNode, addr address.Address) ethtypes.EthAddress { +func getEthAddress(ctx context.Context, t *testing.T, client *kit.TestFullNode, addr address.Address) ethtypes.EthAddress { head, err := client.ChainHead(ctx) require.NoError(t, err) @@ -1143,28 +1133,28 @@ func invokeLogFourData(t *testing.T, client *kit.TestFullNode, iterations int) ( ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() - fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, EventsContract.Filename) + fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, kit.EventsContract.Filename) invocations := make([]Invocation, iterations) for i := range invocations { invocations[i] = Invocation{ Sender: fromAddr, Target: idAddr, - Selector: EventsContract.Fn["log_four_data"], + Selector: kit.EventsContract.Fn["log_four_data"], Data: nil, } } messages := invokeAndWaitUntilAllOnChain(t, client, invocations) - ethAddr := getContractEthAddress(ctx, t, client, idAddr) + ethAddr := getEthAddress(ctx, t, client, idAddr) return ethAddr, messages } func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *kit.TestFullNode) (ethtypes.EthAddress, ethtypes.EthAddress, []Invocation) { - sender1, contract1 := client.EVM().DeployContractFromFilename(ctx, EventMatrixContract.Filename) - sender2, contract2 := client.EVM().DeployContractFromFilename(ctx, EventMatrixContract.Filename) + sender1, contract1 := client.EVM().DeployContractFromFilename(ctx, kit.EventMatrixContract.Filename) + sender2, contract2 := client.EVM().DeployContractFromFilename(ctx, kit.EventMatrixContract.Filename) invocations := []Invocation{ // log EventZeroData() @@ -1172,7 +1162,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventZeroData"], + Selector: kit.EventMatrixContract.Fn["logEventZeroData"], Data: nil, }, @@ -1182,7 +1172,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventOneData"], + Selector: kit.EventMatrixContract.Fn["logEventOneData"], Data: packUint64Values(23), }, @@ -1192,7 +1182,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventOneIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexed"], Data: packUint64Values(44), }, @@ -1203,7 +1193,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender2, Target: contract2, - Selector: EventMatrixContract.Fn["logEventTwoIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventTwoIndexed"], Data: packUint64Values(44, 19), }, @@ -1213,7 +1203,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventOneData"], + Selector: kit.EventMatrixContract.Fn["logEventOneData"], Data: packUint64Values(44), }, @@ -1223,7 +1213,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventTwoData"], + Selector: kit.EventMatrixContract.Fn["logEventTwoData"], Data: packUint64Values(555, 666), }, @@ -1232,7 +1222,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender2, Target: contract2, - Selector: EventMatrixContract.Fn["logEventZeroData"], + Selector: kit.EventMatrixContract.Fn["logEventZeroData"], Data: nil, }, @@ -1242,7 +1232,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventThreeData"], + Selector: kit.EventMatrixContract.Fn["logEventThreeData"], Data: packUint64Values(1, 2, 3), }, @@ -1254,7 +1244,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract2, - Selector: EventMatrixContract.Fn["logEventThreeIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventThreeIndexed"], Data: packUint64Values(44, 27, 19), }, @@ -1265,7 +1255,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventOneIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexedWithData"], Data: packUint64Values(44, 19), }, @@ -1276,7 +1266,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventOneIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexedWithData"], Data: packUint64Values(46, 12), }, @@ -1288,7 +1278,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventTwoIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventTwoIndexedWithData"], Data: packUint64Values(44, 27, 19), }, @@ -1301,7 +1291,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventThreeIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventThreeIndexedWithData"], Data: packUint64Values(44, 27, 19, 12), }, @@ -1312,7 +1302,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender2, Target: contract2, - Selector: EventMatrixContract.Fn["logEventOneIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventOneIndexedWithData"], Data: packUint64Values(50, 9), }, @@ -1324,7 +1314,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventTwoIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventTwoIndexedWithData"], Data: packUint64Values(46, 27, 19), }, @@ -1336,7 +1326,7 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventTwoIndexedWithData"], + Selector: kit.EventMatrixContract.Fn["logEventTwoIndexedWithData"], Data: packUint64Values(46, 14, 19), }, // log EventTwoIndexed(44,19) from contract1 @@ -1346,13 +1336,13 @@ func prepareEventMatrixInvocations(ctx context.Context, t *testing.T, client *ki { Sender: sender1, Target: contract1, - Selector: EventMatrixContract.Fn["logEventTwoIndexed"], + Selector: kit.EventMatrixContract.Fn["logEventTwoIndexed"], Data: packUint64Values(40, 20), }, } - ethAddr1 := getContractEthAddress(ctx, t, client, contract1) - ethAddr2 := getContractEthAddress(ctx, t, client, contract2) + ethAddr1 := getEthAddress(ctx, t, client, contract1) + ethAddr2 := getEthAddress(ctx, t, client, contract2) return ethAddr1, ethAddr2, invocations } @@ -1374,20 +1364,20 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock return []filterTestCase{ { name: "find all EventZeroData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventZeroData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventZeroData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventZeroData"], + kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, }, { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventZeroData"], + kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, }, @@ -1395,20 +1385,20 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventOneData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneData"], + kit.EventMatrixContract.Ev["EventOneData"], }, Data: packUint64Values(23), }, { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneData"], + kit.EventMatrixContract.Ev["EventOneData"], }, Data: packUint64Values(44), }, @@ -1416,13 +1406,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventTwoData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoData"], + kit.EventMatrixContract.Ev["EventTwoData"], }, Data: packUint64Values(555, 666), }, @@ -1430,13 +1420,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventThreeData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeData"], + kit.EventMatrixContract.Ev["EventThreeData"], }, Data: packUint64Values(1, 2, 3), }, @@ -1444,13 +1434,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneIndexed events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventOneIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexed"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexed"], + kit.EventMatrixContract.Ev["EventOneIndexed"], paddedUint64(44), }, Data: nil, @@ -1459,13 +1449,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoIndexed events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventTwoIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexed"])).Filter(), expected: []ExpectedEthLog{ { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexed"], + kit.EventMatrixContract.Ev["EventTwoIndexed"], paddedUint64(44), paddedUint64(19), }, @@ -1474,7 +1464,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexed"], + kit.EventMatrixContract.Ev["EventTwoIndexed"], paddedUint64(40), paddedUint64(20), }, @@ -1484,13 +1474,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeIndexed events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventThreeIndexed"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeIndexed"])).Filter(), expected: []ExpectedEthLog{ { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexed"], + kit.EventMatrixContract.Ev["EventThreeIndexed"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1501,13 +1491,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventOneIndexedWithData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventOneIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexedWithData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(44), }, Data: paddedUint64(19), @@ -1515,7 +1505,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(46), }, Data: paddedUint64(12), @@ -1523,7 +1513,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(50), }, Data: paddedUint64(9), @@ -1532,13 +1522,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventTwoIndexedWithData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventTwoIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(44), paddedUint64(27), }, @@ -1547,7 +1537,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(27), }, @@ -1556,7 +1546,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(14), }, @@ -1566,13 +1556,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all EventThreeIndexedWithData events", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventThreeIndexedWithData"])).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventThreeIndexedWithData"])).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexedWithData"], + kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1584,13 +1574,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { name: "find all events with topic2 of 44", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(44))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(44))).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexed"], + kit.EventMatrixContract.Ev["EventOneIndexed"], paddedUint64(44), }, Data: nil, @@ -1598,7 +1588,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexed"], + kit.EventMatrixContract.Ev["EventTwoIndexed"], paddedUint64(44), paddedUint64(19), }, @@ -1607,7 +1597,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexed"], + kit.EventMatrixContract.Ev["EventThreeIndexed"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1617,7 +1607,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(44), }, Data: paddedUint64(19), @@ -1625,7 +1615,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(44), paddedUint64(27), }, @@ -1634,7 +1624,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexedWithData"], + kit.EventMatrixContract.Ev["EventThreeIndexedWithData"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1645,13 +1635,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 46", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46))).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(46), }, Data: paddedUint64(12), @@ -1659,7 +1649,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(27), }, @@ -1668,7 +1658,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(14), }, @@ -1678,13 +1668,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 50", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(50))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(50))).Filter(), expected: []ExpectedEthLog{ { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(50), }, Data: paddedUint64(9), @@ -1693,13 +1683,13 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock }, { name: "find all events with topic2 of 46 or 50", - spec: newEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46)), paddedEthHash(paddedUint64(50))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).Topic2OneOf(paddedEthHash(paddedUint64(46)), paddedEthHash(paddedUint64(50))).Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(46), }, Data: paddedUint64(12), @@ -1707,7 +1697,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(27), }, @@ -1716,7 +1706,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(14), }, @@ -1725,7 +1715,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(50), }, Data: paddedUint64(9), @@ -1735,9 +1725,9 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { name: "find all events with topic1 of EventTwoIndexedWithData and topic3 of 27", - spec: newEthFilterBuilder(). + spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). - Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventTwoIndexedWithData"])). + Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"])). Topic3OneOf(paddedEthHash(paddedUint64(27))). Filter(), @@ -1745,7 +1735,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(44), paddedUint64(27), }, @@ -1754,7 +1744,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(46), paddedUint64(27), }, @@ -1765,9 +1755,9 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { name: "find all events with topic1 of EventTwoIndexedWithData or EventOneIndexed and topic2 of 44", - spec: newEthFilterBuilder(). + spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). - Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventTwoIndexedWithData"]), paddedEthHash(EventMatrixContract.Ev["EventOneIndexed"])). + Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventTwoIndexedWithData"]), paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexed"])). Topic2OneOf(paddedEthHash(paddedUint64(44))). Filter(), @@ -1775,7 +1765,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexedWithData"], + kit.EventMatrixContract.Ev["EventTwoIndexedWithData"], paddedUint64(44), paddedUint64(27), }, @@ -1784,7 +1774,7 @@ func getTopicFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlock { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexed"], + kit.EventMatrixContract.Ev["EventOneIndexed"], paddedUint64(44), }, Data: nil, @@ -1799,20 +1789,20 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo return []filterTestCase{ { name: "find all events from contract2", - spec: newEthFilterBuilder().FromBlock(fromBlock).AddressOneOf(contract2).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).AddressOneOf(contract2).Filter(), expected: []ExpectedEthLog{ { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventZeroData"], + kit.EventMatrixContract.Ev["EventZeroData"], }, Data: nil, }, { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexed"], + kit.EventMatrixContract.Ev["EventThreeIndexed"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1822,7 +1812,7 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexed"], + kit.EventMatrixContract.Ev["EventTwoIndexed"], paddedUint64(44), paddedUint64(19), }, @@ -1831,7 +1821,7 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(50), }, Data: paddedUint64(9), @@ -1841,13 +1831,13 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { name: "find all events with topic2 of 44 from contract2", - spec: newEthFilterBuilder().FromBlock(fromBlock).AddressOneOf(contract2).Topic2OneOf(paddedEthHash(paddedUint64(44))).Filter(), + spec: kit.NewEthFilterBuilder().FromBlock(fromBlock).AddressOneOf(contract2).Topic2OneOf(paddedEthHash(paddedUint64(44))).Filter(), expected: []ExpectedEthLog{ { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventThreeIndexed"], + kit.EventMatrixContract.Ev["EventThreeIndexed"], paddedUint64(44), paddedUint64(27), paddedUint64(19), @@ -1857,7 +1847,7 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventTwoIndexed"], + kit.EventMatrixContract.Ev["EventTwoIndexed"], paddedUint64(44), paddedUint64(19), }, @@ -1868,17 +1858,17 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { name: "find all EventOneIndexedWithData events from contract1 or contract2", - spec: newEthFilterBuilder(). + spec: kit.NewEthFilterBuilder(). FromBlockEpoch(0). AddressOneOf(contract1, contract2). - Topic1OneOf(paddedEthHash(EventMatrixContract.Ev["EventOneIndexedWithData"])). + Topic1OneOf(paddedEthHash(kit.EventMatrixContract.Ev["EventOneIndexedWithData"])). Filter(), expected: []ExpectedEthLog{ { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(44), }, Data: paddedUint64(19), @@ -1886,7 +1876,7 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { Address: contract1, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(46), }, Data: paddedUint64(12), @@ -1894,7 +1884,7 @@ func getAddressFilterTestCases(contract1, contract2 ethtypes.EthAddress, fromBlo { Address: contract2, Topics: []ethtypes.EthBytes{ - EventMatrixContract.Ev["EventOneIndexedWithData"], + kit.EventMatrixContract.Ev["EventOneIndexedWithData"], paddedUint64(50), }, Data: paddedUint64(9), @@ -1923,6 +1913,7 @@ type ExpectedEthLog struct { } func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedEthLog, messages map[ethtypes.EthHash]msgInTipset) { + t.Helper() require := require.New(t) t.Logf("got %d ethlogs, wanted %d", len(actual), len(expected)) @@ -1992,7 +1983,7 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE buf.WriteString(fmt.Sprintf("event %d\n", i)) buf.WriteString(fmt.Sprintf(" emitter: %v\n", ev.Emitter)) for _, en := range ev.Entries { - buf.WriteString(fmt.Sprintf(" %s=%x\n", en.Key, decodeLogBytes(en.Value))) + buf.WriteString(fmt.Sprintf(" %s=%x\n", en.Key, en.Value)) } } @@ -2015,23 +2006,16 @@ func AssertEthLogs(t *testing.T, actual []*ethtypes.EthLog, expected []ExpectedE func parseEthLogsFromSubscriptionResponses(subResponses []ethtypes.EthSubscriptionResponse) ([]*ethtypes.EthLog, error) { elogs := make([]*ethtypes.EthLog, 0, len(subResponses)) for i := range subResponses { - rlist, ok := subResponses[i].Result.([]interface{}) + rmap, ok := subResponses[i].Result.(map[string]interface{}) if !ok { - return nil, xerrors.Errorf("expected subscription result to be []interface{}, but was %T", subResponses[i].Result) + return nil, xerrors.Errorf("expected subscription result entry to be map[string]interface{}, but was %T", subResponses[i].Result) } - for _, r := range rlist { - rmap, ok := r.(map[string]interface{}) - if !ok { - return nil, xerrors.Errorf("expected subscription result entry to be map[string]interface{}, but was %T", r) - } - - elog, err := ParseEthLog(rmap) - if err != nil { - return nil, err - } - elogs = append(elogs, elog) + elog, err := ParseEthLog(rmap) + if err != nil { + return nil, err } + elogs = append(elogs, elog) } return elogs, nil @@ -2195,18 +2179,6 @@ func paddedEthHash(orig []byte) ethtypes.EthHash { return ret } -func ethTopicHash(sig string) []byte { - hasher := sha3.NewLegacyKeccak256() - hasher.Write([]byte(sig)) - return hasher.Sum(nil) -} - -func ethFunctionHash(sig string) []byte { - hasher := sha3.NewLegacyKeccak256() - hasher.Write([]byte(sig)) - return hasher.Sum(nil)[:4] -} - func packUint64Values(vals ...uint64) []byte { ret := []byte{} for _, v := range vals { @@ -2228,86 +2200,3 @@ func unpackUint64Values(data []byte) []uint64 { } return vals } - -func newEthFilterBuilder() *ethFilterBuilder { return ðFilterBuilder{} } - -type ethFilterBuilder struct { - filter ethtypes.EthFilterSpec -} - -func (e *ethFilterBuilder) Filter() *ethtypes.EthFilterSpec { return &e.filter } - -func (e *ethFilterBuilder) FromBlock(v string) *ethFilterBuilder { - e.filter.FromBlock = &v - return e -} - -func (e *ethFilterBuilder) FromBlockEpoch(v abi.ChainEpoch) *ethFilterBuilder { - s := ethtypes.EthUint64(v).Hex() - e.filter.FromBlock = &s - return e -} - -func (e *ethFilterBuilder) ToBlock(v string) *ethFilterBuilder { - e.filter.ToBlock = &v - return e -} - -func (e *ethFilterBuilder) ToBlockEpoch(v abi.ChainEpoch) *ethFilterBuilder { - s := ethtypes.EthUint64(v).Hex() - e.filter.ToBlock = &s - return e -} - -func (e *ethFilterBuilder) BlockHash(h ethtypes.EthHash) *ethFilterBuilder { - e.filter.BlockHash = &h - return e -} - -func (e *ethFilterBuilder) AddressOneOf(as ...ethtypes.EthAddress) *ethFilterBuilder { - e.filter.Address = as - return e -} - -func (e *ethFilterBuilder) Topic1OneOf(hs ...ethtypes.EthHash) *ethFilterBuilder { - if len(e.filter.Topics) == 0 { - e.filter.Topics = make(ethtypes.EthTopicSpec, 1) - } - e.filter.Topics[0] = hs - return e -} - -func (e *ethFilterBuilder) Topic2OneOf(hs ...ethtypes.EthHash) *ethFilterBuilder { - for len(e.filter.Topics) < 2 { - e.filter.Topics = append(e.filter.Topics, nil) - } - e.filter.Topics[1] = hs - return e -} - -func (e *ethFilterBuilder) Topic3OneOf(hs ...ethtypes.EthHash) *ethFilterBuilder { - for len(e.filter.Topics) < 3 { - e.filter.Topics = append(e.filter.Topics, nil) - } - e.filter.Topics[2] = hs - return e -} - -func (e *ethFilterBuilder) Topic4OneOf(hs ...ethtypes.EthHash) *ethFilterBuilder { - for len(e.filter.Topics) < 4 { - e.filter.Topics = append(e.filter.Topics, nil) - } - e.filter.Topics[3] = hs - return e -} - -func decodeLogBytes(orig []byte) []byte { - if len(orig) == 0 { - return orig - } - decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig))) - if err != nil { - return orig - } - return decoded -} diff --git a/itests/eth_transactions_test.go b/itests/eth_transactions_test.go index 357f411c9..9afeb7bd5 100644 --- a/itests/eth_transactions_test.go +++ b/itests/eth_transactions_test.go @@ -117,11 +117,9 @@ func TestLegacyTransaction(t *testing.T) { require.NoError(t, err) _, err = client.EVM().EthSendRawTransaction(ctx, txBytes) require.ErrorContains(t, err, "legacy transaction is not supported") - } func TestContractDeploymentValidSignature(t *testing.T) { - blockTime := 100 * time.Millisecond client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) @@ -270,7 +268,6 @@ func TestContractInvocation(t *testing.T) { // Success. require.EqualValues(t, ethtypes.EthUint64(0x1), receipt.Status) - } func deployContractTx(ctx context.Context, client *kit.TestFullNode, ethAddr ethtypes.EthAddress, contract []byte) (*ethtypes.EthTxArgs, error) { diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 14b767621..51aff1aac 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -3,6 +3,7 @@ package itests import ( "bytes" "context" + "crypto/rand" "encoding/binary" "encoding/hex" "fmt" @@ -123,7 +124,7 @@ func TestFEVMRecursiveFail(t *testing.T) { t.Run(fmt.Sprintf("TestFEVMRecursiveFail%d", failCallCount), func(t *testing.T) { _, wait, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "recursiveCall(uint256)", buildInputFromuint64(failCallCount)) require.Error(t, err) - require.Equal(t, exitcode.ExitCode(23), wait.Receipt.ExitCode) + require.Equal(t, exitcode.ExitCode(37), wait.Receipt.ExitCode) }) } } @@ -150,24 +151,26 @@ func TestFEVMRecursive2(t *testing.T) { require.Equal(t, 2, len(events)) } -// TestFEVMBasic does a basic fevm contract installation and invocation -// recursive delegate call succeeds up to 238 times -func TestFEVMRecursiveDelegatecall(t *testing.T) { +// TestFEVMRecursiveDelegatecallCount tests the maximum delegatecall recursion depth. It currently +// succeeds succeeds up to 237 times. +func TestFEVMRecursiveDelegatecallCount(t *testing.T) { ctx, cancel, client := kit.SetupFEVMTest(t) defer cancel() + highestSuccessCount := uint64(235) + filename := "contracts/RecursiveDelegeatecall.hex" + recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(1)) + recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(2)) + recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(10)) + recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(100)) + recursiveDelegatecallSuccess(ctx, t, client, filename, highestSuccessCount) - //success with 238 or fewer calls - for i := uint64(1); i <= 238; i += 30 { - recursiveDelegatecallSuccess(ctx, t, client, filename, i) - } - recursiveDelegatecallSuccess(ctx, t, client, filename, uint64(238)) + recursiveDelegatecallFail(ctx, t, client, filename, highestSuccessCount+1) + recursiveDelegatecallFail(ctx, t, client, filename, uint64(1000)) + recursiveDelegatecallFail(ctx, t, client, filename, uint64(10000000)) - for i := uint64(239); i <= 800; i += 40 { - recursiveDelegatecallFail(ctx, t, client, filename, i) - } } // TestFEVMBasic does a basic fevm contract installation and invocation @@ -470,10 +473,9 @@ func TestFEVMSendGasLimit(t *testing.T) { } // TestFEVMDelegateCall deploys the two contracts in TestFEVMDelegateCall but instead of A calling B, A calls A which should cause A to cause A in an infinite loop and should give a reasonable error -// XXX should not be fatal errors func TestFEVMDelegateCallRecursiveFail(t *testing.T) { - //TODO change the gas limit of this invocation and confirm that the number of errors is different - //also TODO should we not have fatal error show up here? + //TODO change the gas limit of this invocation and confirm that the number of errors is + // different ctx, cancel, client := kit.SetupFEVMTest(t) defer cancel() @@ -486,17 +488,16 @@ func TestFEVMDelegateCallRecursiveFail(t *testing.T) { inputDataValue := inputDataFromArray([]byte{7}) inputData := append(inputDataContract, inputDataValue...) - //verify that the returned value of the call to setvars is 7 + //verify that we run out of gas then revert. _, wait, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, actorAddr, "setVarsSelf(address,uint256)", inputData) require.Error(t, err) - require.Equal(t, exitcode.SysErrorIllegalArgument, wait.Receipt.ExitCode) + require.Equal(t, exitcode.ExitCode(33), wait.Receipt.ExitCode) //assert no fatal errors but still there are errors:: errorAny := "fatal error" require.NotContains(t, err.Error(), errorAny) } -// XXX Currently fails as self destruct has a bug // TestFEVMTestSendValueThroughContracts creates A and B contract and exchanges value // and self destructs and accounts for value sent func TestFEVMTestSendValueThroughContractsAndDestroy(t *testing.T) { @@ -601,10 +602,10 @@ func TestFEVMRecursiveActorCall(t *testing.T) { t.Run("n=200,r=32", testN(200, 32, exitcode.Ok)) t.Run("n=251,r=32", testN(251, 32, exitcode.Ok)) - t.Run("n=0,r=254", testN(0, 254, exitcode.Ok)) + t.Run("n=0,r=252", testN(0, 252, exitcode.Ok)) t.Run("n=251,r=166", testN(251, 166, exitcode.Ok)) - t.Run("n=0,r=256-fails", testN(0, 256, exitcode.ExitCode(33))) // 33 means transaction reverted + t.Run("n=0,r=253-fails", testN(0, 253, exitcode.ExitCode(33))) // 33 means transaction reverted t.Run("n=251,r=167-fails", testN(251, 167, exitcode.ExitCode(33))) } @@ -704,3 +705,84 @@ func TestFEVMRecursiveActorCallEstimate(t *testing.T) { t.Run("n=50", testN(50)) t.Run("n=100", testN(100)) } + +// TestFEVM deploys a contract while sending value to it +func TestFEVMDeployWithValue(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //testValue is the amount sent when the contract is created + //at the end we check that the new contract has a balance of testValue + testValue := big.NewInt(20) + + // deploy DeployValueTest which creates NewContract + // testValue is sent to DeployValueTest and that amount is + // also sent to NewContract + filenameActor := "contracts/DeployValueTest.hex" + fromAddr, idAddr := client.EVM().DeployContractFromFilenameWithValue(ctx, filenameActor, testValue) + + //call getNewContractBalance to find the value of NewContract + ret, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "getNewContractBalance()", []byte{}) + require.NoError(t, err) + + contractBalance, err := decodeOutputToUint64(ret) + require.NoError(t, err) + + //require balance of NewContract is testValue + require.Equal(t, testValue.Uint64(), contractBalance) +} + +func TestFEVMDestroyCreate2(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //deploy create2 factory contract + filename := "contracts/Create2Factory.hex" + fromAddr, idAddr := client.EVM().DeployContractFromFilename(ctx, filename) + + //construct salt for create2 + salt := make([]byte, 32) + _, err := rand.Read(salt) + require.NoError(t, err) + + //deploy contract using create2 factory + selfDestructAddress, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "deploy(bytes32)", salt) + require.NoError(t, err) + + //convert to filecoin actor address so we can call InvokeContractByFuncName + ea, err := ethtypes.CastEthAddress(selfDestructAddress[12:]) + require.NoError(t, err) + selfDestructAddressActor, err := ea.ToFilecoinAddress() + require.NoError(t, err) + + //read sender property from contract + ret, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + + //assert contract has correct data + ethFromAddr := inputDataFromFrom(ctx, t, client, fromAddr) + require.Equal(t, ethFromAddr, ret) + + //run test() which 1.calls sefldestruct 2. verifies sender() is the correct value 3. attempts and fails to deploy via create2 + testSenderAddress, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "test(address)", selfDestructAddress) + require.NoError(t, err) + require.Equal(t, testSenderAddress, ethFromAddr) + + //read sender() but get response of 0x0 because of self destruct + senderAfterDestroy, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + require.Equal(t, []byte{}, senderAfterDestroy) + + // deploy new contract at same address usign same salt + newAddressSelfDestruct, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, idAddr, "deploy(bytes32)", salt) + require.NoError(t, err) + require.Equal(t, newAddressSelfDestruct, selfDestructAddress) + + //verify sender() property is correct + senderSecondCall, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, selfDestructAddressActor, "sender()", []byte{}) + require.NoError(t, err) + + //assert contract has correct data + require.Equal(t, ethFromAddr, senderSecondCall) + +} diff --git a/itests/kit/evm.go b/itests/kit/evm.go index e3d717a33..8a764793c 100644 --- a/itests/kit/evm.go +++ b/itests/kit/evm.go @@ -5,6 +5,7 @@ import ( "context" "encoding/binary" "encoding/hex" + "errors" "fmt" "os" "testing" @@ -42,19 +43,18 @@ func (f *TestFullNode) EVM() *EVM { return &EVM{f} } -func (e *EVM) DeployContract(ctx context.Context, sender address.Address, bytecode []byte) eam.CreateReturn { - var err error +func (e *EVM) DeployContractWithValue(ctx context.Context, sender address.Address, bytecode []byte, value big.Int) eam.CreateReturn { require := require.New(e.t) method := builtintypes.MethodsEAM.CreateExternal initcode := abi.CborBytes(bytecode) - params, err := actors.SerializeParams(&initcode) - require.NoError(err) + params, errActors := actors.SerializeParams(&initcode) + require.NoError(errActors) msg := &types.Message{ To: builtintypes.EthereumAddressManagerActorAddr, From: sender, - Value: big.Zero(), + Value: value, Method: method, Params: params, } @@ -76,8 +76,11 @@ func (e *EVM) DeployContract(ctx context.Context, sender address.Address, byteco return result } +func (e *EVM) DeployContract(ctx context.Context, sender address.Address, bytecode []byte) eam.CreateReturn { + return e.DeployContractWithValue(ctx, sender, bytecode, big.Zero()) +} -func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string) (address.Address, address.Address) { +func (e *EVM) DeployContractFromFilenameWithValue(ctx context.Context, binFilename string, value big.Int) (address.Address, address.Address) { contractHex, err := os.ReadFile(binFilename) require.NoError(e.t, err) @@ -90,12 +93,15 @@ func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string fromAddr, err := e.WalletDefaultAddress(ctx) require.NoError(e.t, err) - result := e.DeployContract(ctx, fromAddr, contract) + result := e.DeployContractWithValue(ctx, fromAddr, contract, value) idAddr, err := address.NewIDAddress(result.ActorID) require.NoError(e.t, err) return fromAddr, idAddr } +func (e *EVM) DeployContractFromFilename(ctx context.Context, binFilename string) (address.Address, address.Address) { + return e.DeployContractFromFilenameWithValue(ctx, binFilename, big.Zero()) +} func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target address.Address, selector []byte, inputData []byte) (*api.MsgLookup, error) { params := append(selector, inputData...) @@ -126,7 +132,11 @@ func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target if err != nil { return nil, err } - + if !wait.Receipt.ExitCode.IsSuccess() { + result, err := e.StateReplay(ctx, types.EmptyTSK, wait.Message) + require.NoError(e.t, err) + e.t.Log(result.Error) + } return wait, nil } @@ -244,7 +254,9 @@ func (e *EVM) InvokeContractByFuncName(ctx context.Context, fromAddr address.Add return nil, wait, err } if !wait.Receipt.ExitCode.IsSuccess() { - return nil, wait, fmt.Errorf("contract execution failed - %v", wait.Receipt.ExitCode) + result, err := e.StateReplay(ctx, types.EmptyTSK, wait.Message) + require.NoError(e.t, err) + return nil, wait, errors.New(result.Error) } result, err := cbg.ReadByteArray(bytes.NewBuffer(wait.Receipt.Return), uint64(len(wait.Receipt.Return))) if err != nil { @@ -319,7 +331,7 @@ func removeLeadingZeros(data []byte) []byte { } func SetupFEVMTest(t *testing.T) (context.Context, context.CancelFunc, *TestFullNode) { - //make all logs extra quiet for fevm tests + // make all logs extra quiet for fevm tests lvl, err := logging.LevelFromString("error") if err != nil { panic(err) @@ -354,3 +366,77 @@ func (e *EVM) TransferValueOrFail(ctx context.Context, fromAddr address.Address, require.NoError(e.t, err) require.Equal(e.t, exitcode.Ok, mLookup.Receipt.ExitCode) } + +func NewEthFilterBuilder() *EthFilterBuilder { + return &EthFilterBuilder{} +} + +type EthFilterBuilder struct { + filter ethtypes.EthFilterSpec +} + +func (e *EthFilterBuilder) Filter() *ethtypes.EthFilterSpec { return &e.filter } + +func (e *EthFilterBuilder) FromBlock(v string) *EthFilterBuilder { + e.filter.FromBlock = &v + return e +} + +func (e *EthFilterBuilder) FromBlockEpoch(v abi.ChainEpoch) *EthFilterBuilder { + s := ethtypes.EthUint64(v).Hex() + e.filter.FromBlock = &s + return e +} + +func (e *EthFilterBuilder) ToBlock(v string) *EthFilterBuilder { + e.filter.ToBlock = &v + return e +} + +func (e *EthFilterBuilder) ToBlockEpoch(v abi.ChainEpoch) *EthFilterBuilder { + s := ethtypes.EthUint64(v).Hex() + e.filter.ToBlock = &s + return e +} + +func (e *EthFilterBuilder) BlockHash(h ethtypes.EthHash) *EthFilterBuilder { + e.filter.BlockHash = &h + return e +} + +func (e *EthFilterBuilder) AddressOneOf(as ...ethtypes.EthAddress) *EthFilterBuilder { + e.filter.Address = as + return e +} + +func (e *EthFilterBuilder) Topic1OneOf(hs ...ethtypes.EthHash) *EthFilterBuilder { + if len(e.filter.Topics) == 0 { + e.filter.Topics = make(ethtypes.EthTopicSpec, 1) + } + e.filter.Topics[0] = hs + return e +} + +func (e *EthFilterBuilder) Topic2OneOf(hs ...ethtypes.EthHash) *EthFilterBuilder { + for len(e.filter.Topics) < 2 { + e.filter.Topics = append(e.filter.Topics, nil) + } + e.filter.Topics[1] = hs + return e +} + +func (e *EthFilterBuilder) Topic3OneOf(hs ...ethtypes.EthHash) *EthFilterBuilder { + for len(e.filter.Topics) < 3 { + e.filter.Topics = append(e.filter.Topics, nil) + } + e.filter.Topics[2] = hs + return e +} + +func (e *EthFilterBuilder) Topic4OneOf(hs ...ethtypes.EthHash) *EthFilterBuilder { + for len(e.filter.Topics) < 4 { + e.filter.Topics = append(e.filter.Topics, nil) + } + e.filter.Topics[3] = hs + return e +} diff --git a/itests/kit/solidity.go b/itests/kit/solidity.go new file mode 100644 index 000000000..ea9d452f4 --- /dev/null +++ b/itests/kit/solidity.go @@ -0,0 +1,64 @@ +package kit + +import ( + "golang.org/x/crypto/sha3" +) + +func EthTopicHash(sig string) []byte { + hasher := sha3.NewLegacyKeccak256() + hasher.Write([]byte(sig)) + return hasher.Sum(nil) +} + +func EthFunctionHash(sig string) []byte { + hasher := sha3.NewLegacyKeccak256() + hasher.Write([]byte(sig)) + return hasher.Sum(nil)[:4] +} + +// SolidityContractDef holds information about one of the test contracts +type SolidityContractDef struct { + Filename string // filename of the hex of the contract, e.g. contracts/EventMatrix.hex + Fn map[string][]byte // mapping of function names to 32-bit selector + Ev map[string][]byte // mapping of event names to 256-bit signature hashes +} + +var EventMatrixContract = SolidityContractDef{ + Filename: "contracts/EventMatrix.hex", + Fn: map[string][]byte{ + "logEventZeroData": EthFunctionHash("logEventZeroData()"), + "logEventOneData": EthFunctionHash("logEventOneData(uint256)"), + "logEventTwoData": EthFunctionHash("logEventTwoData(uint256,uint256)"), + "logEventThreeData": EthFunctionHash("logEventThreeData(uint256,uint256,uint256)"), + "logEventFourData": EthFunctionHash("logEventFourData(uint256,uint256,uint256,uint256)"), + "logEventOneIndexed": EthFunctionHash("logEventOneIndexed(uint256)"), + "logEventTwoIndexed": EthFunctionHash("logEventTwoIndexed(uint256,uint256)"), + "logEventThreeIndexed": EthFunctionHash("logEventThreeIndexed(uint256,uint256,uint256)"), + "logEventOneIndexedWithData": EthFunctionHash("logEventOneIndexedWithData(uint256,uint256)"), + "logEventTwoIndexedWithData": EthFunctionHash("logEventTwoIndexedWithData(uint256,uint256,uint256)"), + "logEventThreeIndexedWithData": EthFunctionHash("logEventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), + }, + Ev: map[string][]byte{ + "EventZeroData": EthTopicHash("EventZeroData()"), + "EventOneData": EthTopicHash("EventOneData(uint256)"), + "EventTwoData": EthTopicHash("EventTwoData(uint256,uint256)"), + "EventThreeData": EthTopicHash("EventThreeData(uint256,uint256,uint256)"), + "EventFourData": EthTopicHash("EventFourData(uint256,uint256,uint256,uint256)"), + "EventOneIndexed": EthTopicHash("EventOneIndexed(uint256)"), + "EventTwoIndexed": EthTopicHash("EventTwoIndexed(uint256,uint256)"), + "EventThreeIndexed": EthTopicHash("EventThreeIndexed(uint256,uint256,uint256)"), + "EventOneIndexedWithData": EthTopicHash("EventOneIndexedWithData(uint256,uint256)"), + "EventTwoIndexedWithData": EthTopicHash("EventTwoIndexedWithData(uint256,uint256,uint256)"), + "EventThreeIndexedWithData": EthTopicHash("EventThreeIndexedWithData(uint256,uint256,uint256,uint256)"), + }, +} + +var EventsContract = SolidityContractDef{ + Filename: "contracts/events.bin", + Fn: map[string][]byte{ + "log_zero_data": {0x00, 0x00, 0x00, 0x00}, + "log_zero_nodata": {0x00, 0x00, 0x00, 0x01}, + "log_four_data": {0x00, 0x00, 0x00, 0x02}, + }, + Ev: map[string][]byte{}, +} diff --git a/itests/specs/eth_openrpc.json b/itests/specs/eth_openrpc.json new file mode 100644 index 000000000..ed13614e9 --- /dev/null +++ b/itests/specs/eth_openrpc.json @@ -0,0 +1,4392 @@ +{ + "openrpc": "1.2.4", + "info": { + "title": "Ethereum JSON-RPC Specification", + "description": "A specification of the standard interface for Ethereum clients.", + "license": { + "name": "CC0-1.0", + "url": "https://creativecommons.org/publicdomain/zero/1.0/legalcode" + }, + "version": "0.0.0" + }, + "methods": [ + { + "name": "eth_getBlockByHash", + "summary": "Returns information about a block by hash.", + "params": [ + { + "name": "Block hash", + "required": true, + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "name": "Hydrated transactions", + "required": true, + "schema": { + "title": "hydrated", + "type": "boolean" + } + } + ], + "result": { + "name": "Block information", + "schema": { + "title": "Block object", + "type": "object", + "required": [ + "parentHash", + "sha3Uncles", + "miner", + "stateRoot", + "transactionsRoot", + "receiptsRoot", + "logsBloom", + "number", + "gasLimit", + "gasUsed", + "timestamp", + "extraData", + "mixHash", + "nonce", + "size", + "transactions", + "uncles" + ], + "properties": { + "parentHash": { + "title": "Parent block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "sha3Uncles": { + "title": "Ommers hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "miner": { + "title": "Coinbase", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "stateRoot": { + "title": "State root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionsRoot": { + "title": "Transactions root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "receiptsRoot": { + "title": "Receipts root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "logsBloom": { + "title": "Bloom filter", + "type": "string", + "pattern": "^0x[0-9a-f]{512}$" + }, + "difficulty": { + "title": "Difficulty", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "number": { + "title": "Number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "gasLimit": { + "title": "Gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "gasUsed": { + "title": "Gas used", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "timestamp": { + "title": "Timestamp", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "extraData": { + "title": "Extra data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "mixHash": { + "title": "Mix hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "nonce": { + "title": "Nonce", + "type": "string", + "pattern": "^0x[0-9a-f]{16}$" + }, + "totalDifficulty": { + "title": "Total difficult", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "baseFeePerGas": { + "title": "Base fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "size": { + "title": "Block size", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactions": { + "anyOf": [ + { + "title": "Transaction hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "Full transactions", + "type": "array", + "items": { + "oneOf": [ + { + "title": "Signed 1559 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "input", + "maxFeePerGas", + "maxPriorityFeePerGas", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed 2930 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed Legacy Transaction", + "type": "object", + "required": [ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "v", + "value" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "v": { + "title": "v", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + ] + } + } + ] + }, + "uncles": { + "title": "Uncles", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + } + }, + { + "name": "eth_getBlockByNumber", + "summary": "Returns information about a block by number.", + "params": [ + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + }, + { + "name": "Hydrated transactions", + "required": true, + "schema": { + "title": "hydrated", + "type": "boolean" + } + } + ], + "result": { + "name": "Block information", + "schema": { + "title": "Block object", + "type": "object", + "required": [ + "parentHash", + "sha3Uncles", + "miner", + "stateRoot", + "transactionsRoot", + "receiptsRoot", + "logsBloom", + "number", + "gasLimit", + "gasUsed", + "timestamp", + "extraData", + "mixHash", + "nonce", + "size", + "transactions", + "uncles" + ], + "properties": { + "parentHash": { + "title": "Parent block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "sha3Uncles": { + "title": "Ommers hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "miner": { + "title": "Coinbase", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "stateRoot": { + "title": "State root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionsRoot": { + "title": "Transactions root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "receiptsRoot": { + "title": "Receipts root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "logsBloom": { + "title": "Bloom filter", + "type": "string", + "pattern": "^0x[0-9a-f]{512}$" + }, + "difficulty": { + "title": "Difficulty", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "number": { + "title": "Number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "gasLimit": { + "title": "Gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "gasUsed": { + "title": "Gas used", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "timestamp": { + "title": "Timestamp", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "extraData": { + "title": "Extra data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "mixHash": { + "title": "Mix hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "nonce": { + "title": "Nonce", + "type": "string", + "pattern": "^0x[0-9a-f]{16}$" + }, + "totalDifficulty": { + "title": "Total difficult", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "baseFeePerGas": { + "title": "Base fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "size": { + "title": "Block size", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactions": { + "anyOf": [ + { + "title": "Transaction hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "Full transactions", + "type": "array", + "items": { + "oneOf": [ + { + "title": "Signed 1559 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "input", + "maxFeePerGas", + "maxPriorityFeePerGas", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed 2930 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed Legacy Transaction", + "type": "object", + "required": [ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "v", + "value" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "v": { + "title": "v", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + ] + } + } + ] + }, + "uncles": { + "title": "Uncles", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + } + }, + { + "name": "eth_getBlockTransactionCountByHash", + "summary": "Returns the number of transactions in a block from a block matching the given block hash.", + "params": [ + { + "name": "Block hash", + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Transaction count", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getBlockTransactionCountByNumber", + "summary": "Returns the number of transactions in a block matching the given block number.", + "params": [ + { + "name": "Block", + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Transaction count", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getUncleCountByBlockHash", + "summary": "Returns the number of uncles in a block from a block matching the given block hash.", + "params": [ + { + "name": "Block hash", + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Uncle count", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getUncleCountByBlockNumber", + "summary": "Returns the number of transactions in a block matching the given block number.", + "params": [ + { + "name": "Block", + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Uncle count", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_chainId", + "summary": "Returns the chain ID of the current network.", + "params": [], + "result": { + "name": "Chain ID", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_syncing", + "summary": "Returns an object with data about the sync status or false.", + "params": [], + "result": { + "name": "Syncing status", + "schema": { + "title": "Syncing status", + "oneOf": [ + { + "title": "Syncing progress", + "type": "object", + "properties": { + "startingBlock": { + "title": "Starting block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "currentBlock": { + "title": "Current block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "highestBlock": { + "title": "Highest block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Not syncing", + "description": "Should always return false if not syncing.", + "type": "boolean" + } + ] + } + } + }, + { + "name": "eth_coinbase", + "summary": "Returns the client coinbase address.", + "params": [], + "result": { + "name": "Coinbase address", + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + } + }, + { + "name": "eth_accounts", + "summary": "Returns a list of addresses owned by client.", + "params": [], + "result": { + "name": "Accounts", + "schema": { + "title": "Accounts", + "type": "array", + "items": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + } + } + }, + { + "name": "eth_blockNumber", + "summary": "Returns the number of most recent block.", + "params": [], + "result": { + "name": "Block number", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_call", + "summary": "Executes a new message call immediately without creating a transaction on the block chain.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "type": "object", + "title": "Transaction object generic to all types", + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + } + } + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Return data", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "eth_estimateGas", + "summary": "Generates and returns an estimate of how much gas is necessary to allow the transaction to complete.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "type": "object", + "title": "Transaction object generic to all types", + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + } + } + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Gas used", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_createAccessList", + "summary": "Generates an access list for a transaction.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "type": "object", + "title": "Transaction object generic to all types", + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + } + } + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Gas used", + "schema": { + "title": "Access list result", + "type": "object", + "properties": { + "accessList": { + "title": "accessList", + "type": "array", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "error": { + "title": "error", + "type": "string" + }, + "gasUsed": { + "title": "Gas used", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + } + }, + { + "name": "eth_gasPrice", + "summary": "Returns the current price per gas in wei.", + "params": [], + "result": { + "name": "Gas price", + "schema": { + "title": "Gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_maxPriorityFeePerGas", + "summary": "Returns the current maxPriorityFeePerGas per gas in wei.", + "params": [], + "result": { + "name": "Max priority fee per gas", + "schema": { + "title": "Max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_feeHistory", + "summary": "Transaction fee history", + "description": "Returns transaction base fee per gas and effective priority fee per gas for the requested/supported block range.", + "params": [ + { + "name": "blockCount", + "description": "Requested range of blocks. Clients will return less than the requested range if not all blocks are available.", + "required": true, + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + }, + { + "name": "newestBlock", + "description": "Highest block of the requested range.", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + }, + { + "name": "rewardPercentiles", + "description": "A monotonically increasing list of percentile values. For each block in the requested range, the transactions will be sorted in ascending order by effective tip per gas and the coresponding effective tip for the percentile will be determined, accounting for gas consumed.", + "required": true, + "schema": { + "title": "rewardPercentiles", + "type": "array", + "items": { + "title": "rewardPercentile", + "description": "Floating point value between 0 and 100.", + "type": "number" + } + } + } + ], + "result": { + "name": "feeHistoryResult", + "description": "Fee history for the returned block range. This can be a subsection of the requested range if not all blocks are available.", + "schema": { + "title": "feeHistoryResults", + "description": "Fee history results.", + "type": "object", + "required": [ + "oldestBlock", + "baseFeePerGas", + "gasUsedRatio" + ], + "properties": { + "oldestBlock": { + "title": "oldestBlock", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Lowest number block of returned range." + }, + "baseFeePerGas": { + "title": "baseFeePerGasArray", + "description": "An array of block base fees per gas. This includes the next block after the newest of the returned range, because this value can be derived from the newest block. Zeroes are returned for pre-EIP-1559 blocks.", + "type": "array", + "items": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + }, + "reward": { + "title": "rewardArray", + "description": "A two-dimensional array of effective priority fees per gas at the requested block percentiles.", + "type": "array", + "items": { + "title": "rewardPercentile", + "description": "An array of effective priority fee per gas data points from a single block. All zeroes are returned if the block is empty.", + "type": "array", + "items": { + "title": "rewardPercentile", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "A given percentile sample of effective priority fees per gas from a single block in ascending order, weighted by gas used. Zeroes are returned if the block is empty." + } + } + } + } + } + } + }, + { + "name": "eth_newFilter", + "summary": "Creates a filter object, based on filter options, to notify when the state changes (logs).", + "params": [ + { + "name": "Filter", + "schema": { + "title": "filter", + "type": "object", + "properties": { + "fromBlock": { + "title": "from block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "toBlock": { + "title": "to block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "Address(es)", + "oneOf": [ + { + "title": "Address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + { + "title": "Addresses", + "type": "array", + "items": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + } + ] + }, + "topics": { + "title": "Topics", + "type": "array", + "items": { + "title": "Filter Topic List Entry", + "oneOf": [ + { + "title": "Any Topic Match", + "type": "null" + }, + { + "title": "Single Topic Match", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + { + "title": "Multiple Topic Match", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ] + } + } + } + } + } + ], + "result": { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_newBlockFilter", + "summary": "Creates a filter in the node, to notify when a new block arrives.", + "params": [], + "result": { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_newPendingTransactionFilter", + "summary": "Creates a filter in the node, to notify when new pending transactions arrive.", + "params": [], + "result": { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_uninstallFilter", + "summary": "Uninstalls a filter with given id.", + "params": [ + { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + ], + "result": { + "name": "Success", + "schema": { + "type": "boolean" + } + } + }, + { + "name": "eth_getFilterChanges", + "summary": "Polling method for a filter, which returns an array of logs which occurred since last poll.", + "params": [ + { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + ], + "result": { + "name": "Log objects", + "schema": { + "title": "Filter results", + "oneOf": [ + { + "title": "new block hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new transaction hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new logs", + "type": "array", + "items": { + "title": "log", + "type": "object", + "required": [ + "transactionHash" + ], + "properties": { + "removed": { + "title": "removed", + "type": "boolean" + }, + "logIndex": { + "title": "log index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionHash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "data": { + "title": "data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "topics": { + "title": "topics", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + } + ] + } + } + }, + { + "name": "eth_getFilterLogs", + "summary": "Returns an array of all logs matching filter with given id.", + "params": [ + { + "name": "Filter Identifier", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + ], + "result": { + "name": "Log objects", + "schema": { + "title": "Filter results", + "oneOf": [ + { + "title": "new block hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new transaction hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new logs", + "type": "array", + "items": { + "title": "log", + "type": "object", + "required": [ + "transactionHash" + ], + "properties": { + "removed": { + "title": "removed", + "type": "boolean" + }, + "logIndex": { + "title": "log index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionHash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "data": { + "title": "data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "topics": { + "title": "topics", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + } + ] + } + } + }, + { + "name": "eth_getLogs", + "summary": "Returns an array of all logs matching filter with given id.", + "params": [ + { + "name": "Filter", + "schema": { + "title": "filter", + "type": "object", + "properties": { + "fromBlock": { + "title": "from block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "toBlock": { + "title": "to block", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "Address(es)", + "oneOf": [ + { + "title": "Address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + { + "title": "Addresses", + "type": "array", + "items": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + } + ] + }, + "topics": { + "title": "Topics", + "type": "array", + "items": { + "title": "Filter Topic List Entry", + "oneOf": [ + { + "title": "Any Topic Match", + "type": "null" + }, + { + "title": "Single Topic Match", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + { + "title": "Multiple Topic Match", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ] + } + } + } + } + } + ], + "result": { + "name": "Log objects", + "schema": { + "title": "Filter results", + "oneOf": [ + { + "title": "new block hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new transaction hashes", + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "title": "new logs", + "type": "array", + "items": { + "title": "log", + "type": "object", + "required": [ + "transactionHash" + ], + "properties": { + "removed": { + "title": "removed", + "type": "boolean" + }, + "logIndex": { + "title": "log index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionHash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "data": { + "title": "data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "topics": { + "title": "topics", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + } + ] + } + } + }, + { + "name": "eth_mining", + "summary": "Returns whether the client is actively mining new blocks.", + "params": [], + "result": { + "name": "Mining status", + "schema": { + "title": "miningStatus", + "type": "boolean" + } + } + }, + { + "name": "eth_hashrate", + "summary": "Returns the number of hashes per second that the node is mining with.", + "params": [], + "result": { + "name": "Mining status", + "schema": { + "title": "Hashrate", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getWork", + "summary": "Returns the hash of the current block, the seedHash, and the boundary condition to be met (“target”).", + "params": [], + "result": { + "name": "Current work", + "schema": { + "type": "array", + "items": [ + { + "title": "Proof-of-work hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + { + "title": "seed hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + { + "title": "difficulty", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + }, + { + "name": "eth_submitWork", + "summary": "Used for submitting a proof-of-work solution.", + "params": [ + { + "name": "nonce", + "required": true, + "schema": { + "title": "8 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{16}$" + } + }, + { + "name": "hash", + "required": true, + "schema": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "name": "digest", + "required": true, + "schema": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Success", + "schema": { + "type": "boolean" + } + } + }, + { + "name": "eth_submitHashrate", + "summary": "Used for submitting mining hashrate.", + "params": [ + { + "name": "Hashrate", + "required": true, + "schema": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "name": "ID", + "required": true, + "schema": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Success", + "schema": { + "type": "boolean" + } + } + }, + { + "name": "eth_sign", + "summary": "Returns an EIP-191 signature over the provided data.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "Message", + "required": true, + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + ], + "result": { + "name": "Signature", + "schema": { + "title": "65 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{65}$" + } + } + }, + { + "name": "eth_signTransaction", + "summary": "Returns an RLP encoded transaction signed by the specified account.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "type": "object", + "title": "Transaction object generic to all types", + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + } + } + } + } + ], + "result": { + "name": "Encoded transaction", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "eth_getBalance", + "summary": "Returns the balance of the account of given address.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Balance", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getStorageAt", + "summary": "Returns the value from a storage position at a given address.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "Storage slot", + "required": true, + "schema": { + "title": "hex encoded 256 bit unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]{0,31})|0$" + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Value", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "eth_getTransactionCount", + "summary": "Returns the number of transactions sent from an address.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Transaction count", + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "name": "eth_getCode", + "summary": "Returns code at a given address.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "Block", + "required": false, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Bytecode", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "eth_getProof", + "summary": "Returns the merkle proof for a given account and optionally some storage keys.", + "params": [ + { + "name": "Address", + "required": true, + "schema": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + } + }, + { + "name": "StorageKeys", + "required": true, + "schema": { + "title": "Storage keys", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{0,64}$" + } + } + }, + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number, tag, or block hash", + "anyOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + }, + { + "title": "Block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + ] + } + } + ], + "result": { + "name": "Account", + "schema": { + "title": "Account proof", + "type": "object", + "required": [ + "address", + "accountProof", + "balance", + "codeHash", + "nonce", + "storageHash", + "storageProof" + ], + "properties": { + "address": { + "title": "address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "accountProof": { + "title": "accountProof", + "type": "array", + "items": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + }, + "balance": { + "title": "balance", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]{0,31})|0$" + }, + "codeHash": { + "title": "codeHash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]{0,15})|0$" + }, + "storageHash": { + "title": "storageHash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "storageProof": { + "title": "Storage proofs", + "type": "array", + "items": { + "title": "Storage proof", + "type": "object", + "required": [ + "key", + "value", + "proof" + ], + "properties": { + "key": { + "title": "key", + "type": "string", + "pattern": "^0x[0-9a-f]{0,64}$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]{0,31})|0$" + }, + "proof": { + "title": "proof", + "type": "array", + "items": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + } + } + } + } + } + } + }, + { + "name": "eth_sendTransaction", + "summary": "Signs and submits a transaction.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "type": "object", + "title": "Transaction object generic to all types", + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + } + } + } + } + ], + "result": { + "name": "Transaction hash", + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + }, + { + "name": "eth_sendRawTransaction", + "summary": "Submits a raw transaction.", + "params": [ + { + "name": "Transaction", + "required": true, + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + ], + "result": { + "name": "Transaction hash", + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + }, + { + "name": "eth_getTransactionByHash", + "summary": "Returns the information about a transaction requested by transaction hash.", + "params": [ + { + "name": "Transaction hash", + "required": true, + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Transaction information", + "schema": { + "type": "object", + "title": "Transaction information", + "required": [ + "blockHash", + "blockNumber", + "from", + "hash", + "transactionIndex" + ], + "oneOf": [ + { + "title": "Signed 1559 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "input", + "maxFeePerGas", + "maxPriorityFeePerGas", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed 2930 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed Legacy Transaction", + "type": "object", + "required": [ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "v", + "value" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "v": { + "title": "v", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + ], + "properties": { + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "hash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + } + }, + { + "name": "eth_getTransactionByBlockHashAndIndex", + "summary": "Returns information about a transaction by block hash and transaction index position.", + "params": [ + { + "name": "Block hash", + "required": true, + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + }, + { + "name": "Transaction index", + "required": true, + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + ], + "result": { + "name": "Transaction information", + "schema": { + "type": "object", + "title": "Transaction information", + "required": [ + "blockHash", + "blockNumber", + "from", + "hash", + "transactionIndex" + ], + "oneOf": [ + { + "title": "Signed 1559 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "input", + "maxFeePerGas", + "maxPriorityFeePerGas", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed 2930 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed Legacy Transaction", + "type": "object", + "required": [ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "v", + "value" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "v": { + "title": "v", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + ], + "properties": { + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "hash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + } + }, + { + "name": "eth_getTransactionByBlockNumberAndIndex", + "summary": "Returns information about a transaction by block number and transaction index position.", + "params": [ + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + }, + { + "name": "Transaction index", + "required": true, + "schema": { + "title": "hex encoded unsigned integer", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + ], + "result": { + "name": "Transaction information", + "schema": { + "type": "object", + "title": "Transaction information", + "required": [ + "blockHash", + "blockNumber", + "from", + "hash", + "transactionIndex" + ], + "oneOf": [ + { + "title": "Signed 1559 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "input", + "maxFeePerGas", + "maxPriorityFeePerGas", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "maxPriorityFeePerGas": { + "title": "max priority fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Maximum fee per gas the sender is willing to pay to miners in wei" + }, + "maxFeePerGas": { + "title": "max fee per gas", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The maximum total fee per gas the sender is willing to pay (includes the network / base fee and miner / priority fee) in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed 2930 Transaction", + "type": "object", + "required": [ + "accessList", + "chainId", + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "value", + "yParity" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "accessList": { + "title": "accessList", + "type": "array", + "description": "EIP-2930 access list", + "items": { + "title": "Access list entry", + "type": "object", + "properties": { + "address": { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "storageKeys": { + "type": "array", + "items": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "yParity": { + "title": "yParity", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The parity (0 for even, 1 for odd) of the y-value of the secp256k1 signature." + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + }, + { + "title": "Signed Legacy Transaction", + "type": "object", + "required": [ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "type", + "v", + "value" + ], + "properties": { + "type": { + "title": "type", + "type": "string", + "pattern": "^0x([0-9,a-f,A-F]?){1,2}$" + }, + "nonce": { + "title": "nonce", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "to": { + "title": "to address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "gas": { + "title": "gas limit", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "value": { + "title": "value", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "input": { + "title": "input data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "gasPrice": { + "title": "gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The gas price willing to be paid by the sender in wei" + }, + "chainId": { + "title": "chainId", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Chain ID that this transaction is valid on." + }, + "v": { + "title": "v", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "r": { + "title": "r", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "s": { + "title": "s", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + ], + "properties": { + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "from": { + "title": "from address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "hash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + } + } + } + } + }, + { + "name": "eth_getTransactionReceipt", + "summary": "Returns the receipt of a transaction by transaction hash.", + "params": [ + { + "name": "Transaction hash", + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "Receipt Information", + "schema": { + "type": "object", + "title": "Receipt info", + "required": [ + "blockHash", + "blockNumber", + "from", + "cumulativeGasUsed", + "gasUsed", + "logs", + "logsBloom", + "transactionHash", + "transactionIndex", + "effectiveGasPrice" + ], + "properties": { + "transactionHash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "from": { + "title": "from", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "to": { + "title": "to", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$", + "description": "Address of the receiver or null in a contract creation transaction." + }, + "cumulativeGasUsed": { + "title": "cumulative gas used", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The sum of gas used by this transaction and all preceding transactions in the same block." + }, + "gasUsed": { + "title": "gas used", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The amount of gas used for this specific transaction alone." + }, + "contractAddress": { + "title": "contract address", + "description": "The contract address created, if the transaction was a contract creation, otherwise null.", + "oneOf": [ + { + "title": "hex encoded address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + { + "name": null, + "type": "null" + } + ] + }, + "logs": { + "title": "logs", + "type": "array", + "items": { + "title": "log", + "type": "object", + "required": [ + "transactionHash" + ], + "properties": { + "removed": { + "title": "removed", + "type": "boolean" + }, + "logIndex": { + "title": "log index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionIndex": { + "title": "transaction index", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "transactionHash": { + "title": "transaction hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockHash": { + "title": "block hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "blockNumber": { + "title": "block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + "address": { + "title": "address", + "type": "string", + "pattern": "^0x[0-9,a-f,A-F]{40}$" + }, + "data": { + "title": "data", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "topics": { + "title": "topics", + "type": "array", + "items": { + "title": "32 hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + } + } + }, + "logsBloom": { + "title": "logs bloom", + "type": "string", + "pattern": "^0x[0-9a-f]{512}$" + }, + "root": { + "title": "state root", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$", + "description": "The post-transaction state root. Only specified for transactions included before the Byzantium upgrade." + }, + "status": { + "title": "status", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "Either 1 (success) or 0 (failure). Only specified for transactions included after the Byzantium upgrade." + }, + "effectiveGasPrice": { + "title": "effective gas price", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", + "description": "The actual value per gas deducted from the senders account. Before EIP-1559, this is equal to the transaction's gas price. After, it is equal to baseFeePerGas + min(maxFeePerGas - baseFeePerGas, maxPriorityFeePerGas)." + } + } + } + } + }, + { + "name": "debug_getRawHeader", + "summary": "Returns an RLP-encoded header.", + "params": [ + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Header RLP", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "debug_getRawBlock", + "summary": "Returns an RLP-encoded block.", + "params": [ + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Block RLP", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "debug_getRawTransaction", + "summary": "Returns an array of EIP-2718 binary-encoded transactions.", + "params": [ + { + "name": "Transaction hash", + "required": true, + "schema": { + "title": "32 byte hex value", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + } + } + ], + "result": { + "name": "EIP-2718 binary-encoded transaction", + "schema": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + }, + { + "name": "debug_getRawReceipts", + "summary": "Returns an array of EIP-2718 binary-encoded receipts.", + "params": [ + { + "name": "Block", + "required": true, + "schema": { + "title": "Block number or tag", + "oneOf": [ + { + "title": "Block number", + "type": "string", + "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$" + }, + { + "title": "Block tag", + "type": "string", + "enum": [ + "earliest", + "finalized", + "safe", + "latest", + "pending" + ], + "description": "`earliest`: The lowest numbered block the client has available; `finalized`: The most recent crypto-economically secure block, cannot be re-orged outside of manual intervention driven by community coordination; `safe`: The most recent block that is safe from re-orgs under honest majority and certain synchronicity assumptions; `latest`: The most recent block in the canonical chain observed by the client, this block may be re-orged out of the canonical chain even under healthy/normal conditions; `pending`: A sample next block built by the client on top of `latest` and containing the set of transactions usually taken from local mempool. Before the merge transition is finalized, any call querying for `finalized` or `safe` block MUST be responded to with `-39001: Unknown block` error" + } + ] + } + } + ], + "result": { + "name": "Receipts", + "schema": { + "title": "Receipt array", + "type": "array", + "items": { + "title": "hex encoded bytes", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + } + }, + { + "name": "debug_getBadBlocks", + "summary": "Returns an array of recent bad blocks that the client has seen on the network.", + "params": [], + "result": { + "name": "Blocks", + "schema": { + "title": "Bad block array", + "type": "array", + "items": { + "title": "Bad block", + "type": "object", + "required": [ + "block", + "hash", + "rlp" + ], + "properties": { + "block": { + "title": "Block", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + }, + "hash": { + "title": "Hash", + "type": "string", + "pattern": "^0x[0-9a-f]{64}$" + }, + "rlp": { + "title": "RLP", + "type": "string", + "pattern": "^0x[0-9a-f]*$" + } + } + } + } + } + } + ], + "components": {} +} diff --git a/lib/must/must.go b/lib/must/must.go new file mode 100644 index 000000000..e072b4e04 --- /dev/null +++ b/lib/must/must.go @@ -0,0 +1,9 @@ +package must + +func One[R any](r R, err error) R { + if err != nil { + panic(err) + } + + return r +} diff --git a/node/impl/full/dummy.go b/node/impl/full/dummy.go index c1c6ea975..0b4b0080c 100644 --- a/node/impl/full/dummy.go +++ b/node/impl/full/dummy.go @@ -12,7 +12,7 @@ import ( "github.com/filecoin-project/lotus/chain/types/ethtypes" ) -var ErrModuleDisabled = errors.New("module disabled, enable with Fevm.EnableEthRPC / LOTUS_FEVM_ENABLEETHPRC") +var ErrModuleDisabled = errors.New("module disabled, enable with Fevm.EnableEthRPC / LOTUS_FEVM_ENABLEETHRPC") type EthModuleDummy struct{} diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 02d055d03..bfbd6dbda 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -447,6 +447,11 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, return nil, xerrors.Errorf("cannot parse block param: %s", blkParam) } + // StateManager.Call will panic if there is no parent + if ts.Height() == 0 { + return nil, xerrors.Errorf("block param must not specify genesis block") + } + // Try calling until we find a height with no migration. var res *api.InvocResult for { @@ -637,7 +642,7 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint } return ethtypes.EthFeeHistory{ - OldestBlock: oldestBlkHeight, + OldestBlock: ethtypes.EthUint64(oldestBlkHeight), BaseFeePerGas: baseFeeArray, GasUsedRatio: gasUsedRatioArray, }, nil @@ -962,7 +967,6 @@ func (a *EthModule) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam s if msg.To == builtintypes.EthereumAddressManagerActorAddr { // As far as I can tell, the Eth API always returns empty on contract deployment return ethtypes.EthBytes{}, nil - } else if len(invokeResult.MsgRct.Return) > 0 { return cbg.ReadByteArray(bytes.NewReader(invokeResult.MsgRct.Return), uint64(len(invokeResult.MsgRct.Return))) } @@ -1367,14 +1371,14 @@ func ethFilterResultFromEvents(evs []*filter.CollectedEvent, sa StateAPI) (*etht var err error for _, entry := range ev.Entries { - value, err := cborDecodeTopicValue(entry.Value) - if err != nil { - return nil, err + // Skip all events that aren't "raw" data. + if entry.Codec != cid.Raw { + continue } if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 { - log.Topics = append(log.Topics, value) + log.Topics = append(log.Topics, entry.Value) } else { - log.Data = value + log.Data = entry.Value } } @@ -1513,45 +1517,50 @@ func (e *ethSubscription) addFilter(ctx context.Context, f filter.Filter) { e.filters = append(e.filters, f) } +func (e *ethSubscription) send(ctx context.Context, v interface{}) { + resp := ethtypes.EthSubscriptionResponse{ + SubscriptionID: e.id, + Result: v, + } + + outParam, err := json.Marshal(resp) + if err != nil { + log.Warnw("marshaling subscription response", "sub", e.id, "error", err) + return + } + + if err := e.out(ctx, outParam); err != nil { + log.Warnw("sending subscription response", "sub", e.id, "error", err) + return + } +} + func (e *ethSubscription) start(ctx context.Context) { for { select { case <-ctx.Done(): return case v := <-e.in: - resp := ethtypes.EthSubscriptionResponse{ - SubscriptionID: e.id, - } - - var err error switch vt := v.(type) { case *filter.CollectedEvent: - resp.Result, err = ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI) + evs, err := ethFilterResultFromEvents([]*filter.CollectedEvent{vt}, e.StateAPI) + if err != nil { + continue + } + + for _, r := range evs.Results { + e.send(ctx, r) + } case *types.TipSet: - eb, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.StateAPI) + ev, err := newEthBlockFromFilecoinTipSet(ctx, vt, true, e.Chain, e.StateAPI) if err != nil { break } - resp.Result = eb + e.send(ctx, ev) default: log.Warnf("unexpected subscription value type: %T", vt) } - - if err != nil { - continue - } - - outParam, err := json.Marshal(resp) - if err != nil { - log.Warnw("marshaling subscription response", "sub", e.id, "error", err) - continue - } - - if err := e.out(ctx, outParam); err != nil { - log.Warnw("sending subscription response", "sub", e.id, "error", err) - continue - } } } } @@ -1594,7 +1603,7 @@ func newEthBlockFromFilecoinTipSet(ctx context.Context, ts *types.TipSet, fullTx return ethtypes.EthBlock{}, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err) } - block := ethtypes.NewEthBlock() + block := ethtypes.NewEthBlock(len(msgs) > 0) // this seems to be a very expensive way to get gasUsed of the block. may need to find an efficient way to do it gasUsed := int64(0) @@ -1753,6 +1762,7 @@ func ethTxFromNativeMessage(ctx context.Context, msg *types.Message, sa StateAPI Gas: ethtypes.EthUint64(msg.GasLimit), MaxFeePerGas: ethtypes.EthBigInt(msg.GasFeeCap), MaxPriorityFeePerGas: ethtypes.EthBigInt(msg.GasPremium), + AccessList: []ethtypes.EthHash{}, } } @@ -1886,11 +1896,6 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook } if len(events) > 0 { - // TODO return a dummy non-zero bloom to signal that there are logs - // need to figure out how worth it is to populate with a real bloom - // should be feasible here since we are iterating over the logs anyway - receipt.LogsBloom[255] = 0x01 - receipt.Logs = make([]ethtypes.EthLog, 0, len(events)) for i, evt := range events { l := ethtypes.EthLog{ @@ -1903,14 +1908,15 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook } for _, entry := range evt.Entries { - value, err := cborDecodeTopicValue(entry.Value) - if err != nil { - return api.EthTxReceipt{}, xerrors.Errorf("failed to decode event log value: %w", err) + // Ignore any non-raw values/keys. + if entry.Codec != cid.Raw { + continue } if entry.Key == ethtypes.EthTopic1 || entry.Key == ethtypes.EthTopic2 || entry.Key == ethtypes.EthTopic3 || entry.Key == ethtypes.EthTopic4 { - l.Topics = append(l.Topics, value) + ethtypes.EthBloomSet(receipt.LogsBloom, entry.Value) + l.Topics = append(l.Topics, entry.Value) } else { - l.Data = value + l.Data = entry.Value } } @@ -1924,6 +1930,7 @@ func newEthTxReceipt(ctx context.Context, tx ethtypes.EthTx, lookup *api.MsgLook return api.EthTxReceipt{}, xerrors.Errorf("failed to resolve Ethereum address: %w", err) } + ethtypes.EthBloomSet(receipt.LogsBloom, l.Address[:]) receipt.Logs = append(receipt.Logs, l) } } @@ -1967,6 +1974,52 @@ func (m *EthTxHashManager) Revert(ctx context.Context, from, to *types.TipSet) e return nil } +func (m *EthTxHashManager) PopulateExistingMappings(ctx context.Context, minHeight abi.ChainEpoch) error { + if minHeight < build.UpgradeHyggeHeight { + minHeight = build.UpgradeHyggeHeight + } + + ts := m.StateAPI.Chain.GetHeaviestTipSet() + for ts.Height() > minHeight { + for _, block := range ts.Blocks() { + msgs, err := m.StateAPI.Chain.SecpkMessagesForBlock(ctx, block) + if err != nil { + // If we can't find the messages, we've either imported from snapshot or pruned the store + log.Debug("exiting message mapping population at epoch ", ts.Height()) + return nil + } + + for _, msg := range msgs { + m.ProcessSignedMessage(ctx, msg) + } + } + + var err error + ts, err = m.StateAPI.Chain.GetTipSetFromKey(ctx, ts.Parents()) + if err != nil { + return err + } + } + + return nil +} + +func (m *EthTxHashManager) ProcessSignedMessage(ctx context.Context, msg *types.SignedMessage) { + if msg.Signature.Type != crypto.SigTypeDelegated { + return + } + + ethTx, err := newEthTxFromSignedMessage(ctx, msg, m.StateAPI) + if err != nil { + log.Errorf("error converting filecoin message to eth tx: %s", err) + } + + err = m.TransactionHashLookup.UpsertHash(ethTx.Hash, msg.Cid()) + if err != nil { + log.Errorf("error inserting tx mapping to db: %s", err) + } +} + func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager *EthTxHashManager) { for { select { @@ -1976,19 +2029,8 @@ func WaitForMpoolUpdates(ctx context.Context, ch <-chan api.MpoolUpdate, manager if u.Type != api.MpoolAdd { continue } - if u.Message.Signature.Type != crypto.SigTypeDelegated { - continue - } - ethTx, err := newEthTxFromSignedMessage(ctx, u.Message, manager.StateAPI) - if err != nil { - log.Errorf("error converting filecoin message to eth tx: %s", err) - } - - err = manager.TransactionHashLookup.UpsertHash(ethTx.Hash, u.Message.Cid()) - if err != nil { - log.Errorf("error inserting tx mapping to db: %s", err) - } + manager.ProcessSignedMessage(ctx, u.Message) } } } @@ -2009,45 +2051,6 @@ func EthTxHashGC(ctx context.Context, retentionDays int, manager *EthTxHashManag } } -func leftpad32(orig []byte) []byte { - needed := 32 - len(orig) - if needed <= 0 { - return orig - } - ret := make([]byte, 32) - copy(ret[needed:], orig) - return ret -} - -func trimLeadingZeros(b []byte) []byte { - for i := range b { - if b[i] != 0 { - return b[i:] - } - } - return []byte{} -} - -func cborEncodeTopicValue(orig []byte) ([]byte, error) { - var buf bytes.Buffer - err := cbg.WriteByteArray(&buf, trimLeadingZeros(orig)) - if err != nil { - return nil, err - } - return buf.Bytes(), nil -} - -func cborDecodeTopicValue(orig []byte) ([]byte, error) { - if len(orig) == 0 { - return orig, nil - } - decoded, err := cbg.ReadByteArray(bytes.NewReader(orig), uint64(len(orig))) - if err != nil { - return nil, err - } - return leftpad32(decoded), nil -} - func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) { keys := map[string][][]byte{} for idx, vals := range topics { @@ -2057,11 +2060,8 @@ func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) { // Ethereum topics are emitted using `LOG{0..4}` opcodes resulting in topics1..4 key := fmt.Sprintf("t%d", idx+1) for _, v := range vals { - encodedVal, err := cborEncodeTopicValue(v[:]) - if err != nil { - return nil, xerrors.Errorf("failed to encode topic value") - } - keys[key] = append(keys[key], encodedVal) + v := v // copy the ethhash to avoid repeatedly referencing the same one. + keys[key] = append(keys[key], v[:]) } } return keys, nil diff --git a/node/modules/ethmodule.go b/node/modules/ethmodule.go index 9889233f4..eba6c54d1 100644 --- a/node/modules/ethmodule.go +++ b/node/modules/ethmodule.go @@ -2,6 +2,7 @@ package modules import ( "context" + "os" "path/filepath" "go.uber.org/fx" @@ -24,7 +25,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep return nil, err } - transactionHashLookup, err := ethhashlookup.NewTransactionHashLookup(filepath.Join(sqlitePath, "txhash.db")) + dbPath := filepath.Join(sqlitePath, "txhash.db") + + // Check if the db exists, if not, we'll back-fill some entries + _, err = os.Stat(dbPath) + dbAlreadyExists := err == nil + + transactionHashLookup, err := ethhashlookup.NewTransactionHashLookup(dbPath) if err != nil { return nil, err } @@ -40,6 +47,13 @@ func EthModuleAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRep TransactionHashLookup: transactionHashLookup, } + if !dbAlreadyExists { + err = ethTxHashManager.PopulateExistingMappings(mctx, 0) + if err != nil { + return nil, err + } + } + const ChainHeadConfidence = 1 ctx := helpers.LifecycleCtx(mctx, lc)