diff --git a/.circleci/config.yml b/.circleci/config.yml index 0d3b1ba07..e3e7330a5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -628,6 +628,11 @@ workflows: suite: itest-eth_block_hash target: "./itests/eth_block_hash_test.go" + - test: + name: test-itest-eth_bytecode + suite: itest-eth_bytecode + target: "./itests/eth_bytecode_test.go" + - test: name: test-itest-eth_config suite: itest-eth_config @@ -723,6 +728,11 @@ workflows: suite: itest-migration_nv19 target: "./itests/migration_nv19_test.go" + - test: + name: test-itest-migration_nv20 + suite: itest-migration_nv20 + target: "./itests/migration_nv20_test.go" + - test: name: test-itest-mpool_msg_uuid suite: itest-mpool_msg_uuid diff --git a/build/actors/v12.tar.zst b/build/actors/v12.tar.zst new file mode 100644 index 000000000..587c24ea9 Binary files /dev/null and b/build/actors/v12.tar.zst differ diff --git a/build/builtin_actors_gen.go b/build/builtin_actors_gen.go index 4beb8ff68..a63a10c93 100644 --- a/build/builtin_actors_gen.go +++ b/build/builtin_actors_gen.go @@ -7,8 +7,9 @@ import ( ) var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMetadata{{ - Network: "butterflynet", - Version: 8, + Network: "butterflynet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), @@ -29,8 +30,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), }, }, { - Network: "butterflynet", - Version: 9, + Network: "butterflynet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzaceba5qgs4z3imhlxwds5vamahngatvuuglbv5yl3ftfiosj6ud5chs"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), @@ -51,8 +53,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), }, }, { - Network: "butterflynet", - Version: 10, + Network: "butterflynet", + Version: 10, + ManifestCid: MustParseCid("bafy2bzacecjs7xvhtejsh47b2tx2iwe7mbad4kxovbfs7a6wxfl47kcnl25bm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), @@ -73,8 +76,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), }, }, { - Network: "butterflynet", - Version: 11, + Network: "butterflynet", + Version: 11, + ManifestCid: MustParseCid("bafy2bzaced2wq4k4i2deknam6ehbynaoo37bhysud7eze7su3ftlaggwwjuje"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebd5zetyjtragjwrv2nqktct6u2pmsi4eifbanovxohx3a7lszjxi"), @@ -95,8 +99,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebu4joy25gneu2qv3qfm3ktakzalndjrbhekeqrqk3zhotv6nyy2g"), }, }, { - Network: "calibrationnet", - Version: 8, + Network: "butterflynet", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzacec4tgdtsrgbdywc5nzf5ekiw5zuefrasiahb4n5yqwcrwjzcdp4nk"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzaceae6holtld4caox2xood5rpcjotrxj7lnfxvfmhivb3s2ddyj22qw"), + "cron": MustParseCid("bafk2bzaceab2vrkun6ps3hactaumfzgm6zk4sdasiqiedxzdttkvw64hndcdg"), + "datacap": MustParseCid("bafk2bzacecixx45mf6chwktsd2g5krlr35p3g7pkkrvzjeujz4ryhlztpl7fq"), + "eam": MustParseCid("bafk2bzaceciekaxrlgnmosmthbgptpdu2bzdoo7mt67p7cqbdvnxup6xpd6ns"), + "ethaccount": MustParseCid("bafk2bzacecb4ttgbjzkaqrg7phqgao2kxsgeet4wnrr5qmftlfad26v6jpk4o"), + "evm": MustParseCid("bafk2bzacecrwejr7bedjww67ppof3abb6df66w76r7wpuzc426arc4oibndeu"), + "init": MustParseCid("bafk2bzacea5ke6q7je2ofrai7dpw67vat463d5f74g4evvwtcu7dhp4ff6ztk"), + "multisig": MustParseCid("bafk2bzacecs6aws25bvqmyzny3vcilr2xw35jymryu4yzodg7l7gf4bhjpolw"), + "paymentchannel": MustParseCid("bafk2bzacedtewkfsicz2rm4hsjsbagrl2mhmqfdikpsq3ggoct5iqa6caka6a"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzacecqmh47zzzlzbtaueaz2fvhiqnktccfrcqicul4j6tca2bruvtn44"), + "storagemarket": MustParseCid("bafk2bzacecbvqe4k6jyvwovxfnkylj3zpb2vjxkc3ar53x7c2pe5mkokxuyk6"), + "storageminer": MustParseCid("bafk2bzaceczbh2aofwcif4aqycydmnsjkkww4i4yfl4zca5j2dqopbz46dvrg"), + "storagepower": MustParseCid("bafk2bzacealioyiirrvov5rnh63omtsifppcsgba7my2tp7bslhd454wczepy"), + "system": MustParseCid("bafk2bzaceax2qvj3ap2dxvzgjps2vtmfgfrej3hdgk7a5euqdgsmak7ptalaa"), + "verifiedregistry": MustParseCid("bafk2bzaceaeqg3nqpjrgklq6nli6hz73s76hp4bwn6jsa64y22dj3csvmcl32"), + }, +}, { + Network: "calibrationnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedrdn6z3z7xz7lx4wll3tlgktirhllzqxb766dxpaqp3ukxsjfsba"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecruossn66xqbeutqx5r4k2kjzgd43frmwd4qkw6haez44ubvvpxo"), @@ -112,8 +140,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceaihibfu625lbtzdp3tcftscshrmbgghgrc7kzqhxn4455pycpdkm"), }, }, { - Network: "calibrationnet", - Version: 9, + Network: "calibrationnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacedbedgynklc4dgpyxippkxmba2mgtw7ecntoneclsvvl4klqwuyyy"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceavfgpiw6whqigmskk74z4blm22nwjfnzxb4unlqz2e4wg3c5ujpw"), @@ -130,8 +159,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebh7dj6j7yi5vadh7lgqjtq42qi2uq4n6zy2g5vjeathacwn2tscu"), }, }, { - Network: "calibrationnet", - Version: 10, + Network: "calibrationnet", + Version: 10, + ManifestCid: MustParseCid("bafy2bzaceaklxgrzd34i53rm4eeq6477nlq2ckpex27evftbsmjd2yrdbj4ba"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacea7zmrdz2rjbzlbmrmx3ko6pm3cbyqxxgogiqldsccbqffuok7m6s"), @@ -152,8 +182,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceawecz24xbz7robn7ck7k2mprkewvup6q346whbfiybcrvy63qcsa"), }, }, { - Network: "calibrationnet", - Version: 11, + Network: "calibrationnet", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacearpwvmcqlailxyq2d2wtzmtudxqhvfot77tbdqotek5qiq5hyhzg"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacea7zmrdz2rjbzlbmrmx3ko6pm3cbyqxxgogiqldsccbqffuok7m6s"), @@ -174,8 +205,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceawecz24xbz7robn7ck7k2mprkewvup6q346whbfiybcrvy63qcsa"), }, }, { - Network: "caterpillarnet", - Version: 8, + Network: "calibrationnet", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzaced25ta3j6ygs34roprilbtb3f6mxifyfnm7z7ndquaruxzdq3y7lo"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacebhfuz3sv7duvk653544xsxhdn4lsmy7ol7k6gdgancyctvmd7lnq"), + "cron": MustParseCid("bafk2bzacecw2yjb6ysieffa7lk7xd32b3n4ssowvafolt7eq52lp6lk4lkhji"), + "datacap": MustParseCid("bafk2bzaceaot6tv6p4cat3cg5fknq22htosw3p5rwyijmdsraatwqyc4qyero"), + "eam": MustParseCid("bafk2bzacec5untyj6cefdsfm47wckozw6wt6svqqh5dzh63nu4f6dvf26fkco"), + "ethaccount": MustParseCid("bafk2bzacebiyrhz32xwxi6xql67aaq5nrzeelzas472kuwjqmdmgwotpkj35e"), + "evm": MustParseCid("bafk2bzaceblpgzid4qjfavuiht6uwvq2lznshklk2qmf5akm3dzx2fczdqdxc"), + "init": MustParseCid("bafk2bzacedhxbcglnonzruxf2jpczara73eh735wf2kznatx2u4gsuhgqwffq"), + "multisig": MustParseCid("bafk2bzacebv5gdlte2pyovmz6s37me6x2rixaa6a33w6lgqdohmycl23snvwm"), + "paymentchannel": MustParseCid("bafk2bzacea7ngq44gedftjlar3j3ql3dmd7e7xkkb6squgxinfncybfmppmlc"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzacea3yo22x4dsh4axioshrdp42eoeugef3tqtmtwz5untyvth7uc73o"), + "storagemarket": MustParseCid("bafk2bzacecclsfboql3iraf3e66pzuh3h7qp3vgmfurqz26qh5g5nrexjgknc"), + "storageminer": MustParseCid("bafk2bzacedu4chbl36rilas45py4vhqtuj6o7aa5stlvnwef3kshgwcsmha6y"), + "storagepower": MustParseCid("bafk2bzacedu3c67spbf2dmwo77ymkjel6i2o5gpzyksgu2iuwu2xvcnxgfdjg"), + "system": MustParseCid("bafk2bzacea4mtukm5zazygkdbgdf26cpnwwif5n2no7s6tknpxlwy6fpq3mug"), + "verifiedregistry": MustParseCid("bafk2bzacec67wuchq64k7kgrujguukjvdlsl24pgighqdx5vgjhyk6bycrwnc"), + }, +}, { + Network: "caterpillarnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -196,8 +251,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "caterpillarnet", - Version: 9, + Network: "caterpillarnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacebsdvrxmdajiyxq2mxxxppvg2zwvqjzz3pgbsxwh6pvdcjofpmnxw"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -218,8 +274,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "caterpillarnet", - Version: 10, + Network: "caterpillarnet", + Version: 10, + ManifestCid: MustParseCid("bafy2bzaceawh5opc4uqctlzc6xnq3pb7ycchfqwprjysbfa5xlrmiicbbvkrm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -240,8 +297,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "caterpillarnet", - Version: 11, + Network: "caterpillarnet", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacebxr4uvnf5g3373shjzbaca6pf4th6nnfubytjfbrlxcpvbjw4ane"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedfms6w3ghqtljpgsfuiqa6ztjx7kcuin6myjezj6rypj3zjbqms6"), @@ -262,8 +320,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacebzndvdqtdck2y35smcxezldgh6nm6rbkj3g3fmiknsgg2uah235y"), }, }, { - Network: "devnet", - Version: 8, + Network: "caterpillarnet", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzacedn6med544h6r7frzvyq5cvd7dqgnwgpmzgf42d4agoysx6tf475i"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzaceaysjus6ldo45qnedaopwctamtvvk4ga2l4dh7dmdtltsfin4puuk"), + "cron": MustParseCid("bafk2bzaceatq2ltzs2p37nniek3qpkitzlfd7iu2qtupzjtgvtggxglrhj7ay"), + "datacap": MustParseCid("bafk2bzacecgwe56okusbtsfimiwstxe7ova25uvrkj4osk3w5wl2qclvd64bi"), + "eam": MustParseCid("bafk2bzaceak3xbmmyj5glnm65kv5p7zc6u7x2xallwpz7aphqqouadn3jvumm"), + "ethaccount": MustParseCid("bafk2bzacec5bcn2i4ktsc54wx7gf4gwdd6xjcukh43szfya47jicxlwrhfrhk"), + "evm": MustParseCid("bafk2bzacebbc2iv4tw2kfmmcm7k3uxilpqvbjg6jsqbov4n7wqcxvvmtazfbc"), + "init": MustParseCid("bafk2bzacecvlqa2szdyem4gwgks2yk7bfernmzbxgo5felnpqgikyesdyiury"), + "multisig": MustParseCid("bafk2bzacebvqjxop2ald5f5hvu7qqb7ali7iluxcbdd3ssllawco6kafjteqw"), + "paymentchannel": MustParseCid("bafk2bzacebux5gmkddtur2kfebwzrxwqyqh2almlt4bw3v7f4bg3gy2zqjhbe"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzacebhm5w7q7wlxrwgbldolzq5qfcdmcu66j6ty37ppvpwafxzlizxn4"), + "storagemarket": MustParseCid("bafk2bzacebgniq7x22ep4oiithvlzepxo5jsvhuang2vqfz3prozihmviw5ey"), + "storageminer": MustParseCid("bafk2bzacecchnrfi4cgbpis4aagiqkhalgqudjlu25da7rer4ltlgpojersgm"), + "storagepower": MustParseCid("bafk2bzaceaxomr5xbhacbbn5ib6unekjz6igoqr4r4a2taxqcpyb4gpwi6zvk"), + "system": MustParseCid("bafk2bzacebmymcxtwkk6dzgtmkbradncjpsxdqkcwtemhio5acvpm742rguv6"), + "verifiedregistry": MustParseCid("bafk2bzaceae5zbc2h6gpyu6uzsvelvww53p5mujq2dvs3zi74w6mvnigwc3va"), + }, +}, { + Network: "devnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedq7tuibavyqxzkq4uybjj7ly22eu42mjkoehwn5d47xfunmtjm4k"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacea4tlgnp7m6tlldpz3termlwxlnyq24nwd4zdzv4r6nsjuaktuuzc"), @@ -279,8 +361,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceaajgtglewgitshgdi2nzrvq7eihjtyqj5yiamesqun2hujl3xev2"), }, }, { - Network: "devnet", - Version: 9, + Network: "devnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacedozk3jh2j4nobqotkbofodq4chbrabioxbfrygpldgoxs3zwgggk"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaced5llqnqqhypolyuogz3h2wjomugqkrhyhocvly3aoib4c5xiush6"), @@ -297,8 +380,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacednorhcy446agy7ecpmfms2u4aoa3mj2eqomffuoerbik5yavrxyi"), }, }, { - Network: "devnet", - Version: 10, + Network: "devnet", + Version: 10, + ManifestCid: MustParseCid("bafy2bzacedfwwsn5weycwkqrnusc37m6ut2uf42z5qvbukl67wi76mqtgafw2"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebb5txxkfexeaxa2th3rckxsxchzyss3ijgqbicf265h7rre2rvhm"), @@ -319,8 +403,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceb7odugx7meltvt2gra4vogn2g6avbgysivvdccldylusjcfsnfhy"), }, }, { - Network: "devnet", - Version: 11, + Network: "devnet", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacebixrjysarwxdadewlllfp4rwfoejxstwdutghghei54uvuuxlsbq"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebb5txxkfexeaxa2th3rckxsxchzyss3ijgqbicf265h7rre2rvhm"), @@ -341,8 +426,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceb7odugx7meltvt2gra4vogn2g6avbgysivvdccldylusjcfsnfhy"), }, }, { - Network: "hyperspace", - Version: 8, + Network: "devnet", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzaceco52tjbexpijsegolhdkhlziflum4bl27hcjrpnny273t3lsa6tc"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacec6mdvynyu4cxb53tcdbkcu7w7jzxduxqqadi2y2rx2tsm42627tk"), + "cron": MustParseCid("bafk2bzaceaiscwdpdzdooja7hwz56ee3zztjogl4gljkccpefi7uliqtaq2ek"), + "datacap": MustParseCid("bafk2bzacedmfwrwwqmwxtfpvhp33mvt5btq2ewbjfrvfetwnrxt5r37i3ymzk"), + "eam": MustParseCid("bafk2bzaced2lwwrqtkgwxdgadpdbxpxjoh2gsunjg3bgtoubs47p7fbktbu26"), + "ethaccount": MustParseCid("bafk2bzacea5zob56gdcxudkubhol4gijzgwgtaaix4pmv3vpg4ihtsuxbdhqa"), + "evm": MustParseCid("bafk2bzaceacw53ajmggrugzfiag75suv27hvqoduypk24xru3cumctpxotbya"), + "init": MustParseCid("bafk2bzaceahgtz6647nbarvyjwtvjadzd2i2m75jv6nnrq3kgwrjxnvkykmhs"), + "multisig": MustParseCid("bafk2bzaceduhknhgd45j5aey7c7pszbbwqm4vuih4iwbuffjxekqteebuja5q"), + "paymentchannel": MustParseCid("bafk2bzacec5x44xqfgmdvsxr4nwzbcwaotodzffsjsslw64xblr7xgx7jr6c4"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzacebzyuwya26rjjxmtzcszf5hcv54b3l7bz6hbflbx3wmpycbqcq6fa"), + "storagemarket": MustParseCid("bafk2bzaceav2nt4ek457u3ngn7da2gaqblwdumpzhsohp4d7whmubvarkllac"), + "storageminer": MustParseCid("bafk2bzacecxr3rdjaive7opvfyqv3p7tft6ragdozlqd6hciprlknda7u5hk6"), + "storagepower": MustParseCid("bafk2bzaceabvb7af55pgm3xpcc7lqjaupw3dyyokbmhjvbo2ebelizalmugfq"), + "system": MustParseCid("bafk2bzacecp7sswldmz6cbl7lh6y5vtwnn43mvdkgcazcyjjcpjjbtydb2f3w"), + "verifiedregistry": MustParseCid("bafk2bzaced27273xjvuyhxlne2kmbrbtupcxxpdchqbkiyr3dcqoijaok2k7e"), + }, +}, { + Network: "hyperspace", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), @@ -363,8 +472,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), }, }, { - Network: "hyperspace", - Version: 9, + Network: "hyperspace", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacedvffumcvf72f2btjqvece3kpcdorxq5tq76iwcmqbzvsiu526cqm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), @@ -385,8 +495,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), }, }, { - Network: "hyperspace", - Version: 10, + Network: "hyperspace", + Version: 10, + ManifestCid: MustParseCid("bafy2bzacedimb4dzty5tsyy3ucbcxai7crli452wn5cguhpmuelq74i4bffoo"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), @@ -407,8 +518,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), }, }, { - Network: "hyperspace", - Version: 11, + Network: "hyperspace", + Version: 11, + ManifestCid: MustParseCid("bafy2bzaced6hc7ujjmypg6mkrxdmf32oh2udhmhpmwkqyxusdkxoi2uoodyxg"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacecim7uybic2qprbkjhowg7qkniv4zywj5h5g4u4ss72urco2akzuo"), @@ -429,8 +541,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea7rfkjrixaidksnmjehglmavyt56nyeu3sfxu2e3dcpf62oab6tw"), }, }, { - Network: "mainnet", - Version: 8, + Network: "hyperspace", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzacebrhulkwvg46jx5p7kaurdtm5sfs22ecyc7hu7q6t6ckfidkicc6a"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacebmyadah25cxldsl2nwtravvsqh3cfycn2bf2dhcq5dteehk44yv4"), + "cron": MustParseCid("bafk2bzacedppsrfd3ut6mrdjb5sdgydatqgpjy323rdoim7z2os75llafeeic"), + "datacap": MustParseCid("bafk2bzacebtgwijwtn5jh3j6iyta4q3rij4hm45fgs7bm27qcthlrobzlahj4"), + "eam": MustParseCid("bafk2bzacebkpsxhntyjjnmplk7qmyisjr47vqwmckccy746t6df5qfebage2c"), + "ethaccount": MustParseCid("bafk2bzacecs7b5ncwsdao6km4a65zsxhxsuudn5sqy2h4gbrgfurglia5sv2y"), + "evm": MustParseCid("bafk2bzacebu7shvk7drrgyqopnyj7oscsvpdsyudnzv4ugfwryobxe4eevr4i"), + "init": MustParseCid("bafk2bzacedic7xk4yvcohv6kq22vpmlnra67qfp5wtimqkqlkcqm7t7sonwbs"), + "multisig": MustParseCid("bafk2bzaceafuswfpwoemcfrew4af6zgm2vtfr7dcfultbgsufibw5rita6vac"), + "paymentchannel": MustParseCid("bafk2bzacecgypg4duygqz2cvw3xhu4m6jmzbh2kyizddx75azjj4gh76pt662"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzaceat2eebo3v3qqk6pofvsvpt5oditu6ur7pkfc33ebxgghkzoacxsm"), + "storagemarket": MustParseCid("bafk2bzaceb7aaaric5jy3dbbawrbyylqkrvwlzmthw65t3ihcuywa3bl6imuu"), + "storageminer": MustParseCid("bafk2bzacedb7nve7h67r26qzmrsyynsfky6wwgdl5s4jdijmjy6ybfmdgxhuu"), + "storagepower": MustParseCid("bafk2bzacedv5mzkuuy6siqjqginpalbty2tkkiehfq7k4fteuupexohyfskfy"), + "system": MustParseCid("bafk2bzacebvwx4r5zcnc2kb42n4i6c4jglgi53aqrva3rlsiqu5omftj7ldkg"), + "verifiedregistry": MustParseCid("bafk2bzacech26voh3qiqv5xgcdndnqxjj5dq7eiwuhbxqxhzo5q7kim4zauig"), + }, +}, { + Network: "mainnet", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacebogjbpiemi7npzxchgcjjki3tfxon4ims55obfyfleqntteljsea"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedudbf7fc5va57t3tmo63snmt3en4iaidv4vo3qlyacbxaa6hlx6y"), @@ -446,8 +582,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceb3zbkjz3auizmoln2unmxep7dyfcmsre64vnqfhdyh7rkqfoxlw4"), }, }, { - Network: "mainnet", - Version: 9, + Network: "mainnet", + Version: 9, + ManifestCid: MustParseCid("bafy2bzaceb6j6666h36xnhksu3ww4kxb6e25niayfgkdnifaqi6m6ooc66i6i"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacect2p7urje3pylrrrjy3tngn6yaih4gtzauuatf2jllk3ksgfiw2y"), @@ -464,8 +601,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacecf3yodlyudzukumehbuabgqljyhjt5ifiv4vetcfohnvsxzynwga"), }, }, { - Network: "mainnet", - Version: 10, + Network: "mainnet", + Version: 10, + ManifestCid: MustParseCid("bafy2bzaceat4ut5xv3qn4lvvkvwvdn6gtlbnqzvueh67fjqlemw6eled5oqnc"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedsn6i2flkpk6sb4iuejo7gfl5n6fhsdawggtbsihlrrjtvs7oepu"), @@ -486,8 +624,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea2eehyf7h3m6ydh46piu2gtr4fawpqzh3brtmybgi2tyxf5nwj6m"), }, }, { - Network: "mainnet", - Version: 11, + Network: "mainnet", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacea5vylkbby7rb42fknkk4g4byhj7hkqlxp4z4urydi3vlpwsgllik"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacedsn6i2flkpk6sb4iuejo7gfl5n6fhsdawggtbsihlrrjtvs7oepu"), @@ -508,8 +647,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacea2eehyf7h3m6ydh46piu2gtr4fawpqzh3brtmybgi2tyxf5nwj6m"), }, }, { - Network: "testing", - Version: 8, + Network: "mainnet", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzacecyg4biu2uccoekdzen4qxf4qt24deyx6j5rpwfys7qp6lixvzsxo"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacect72amqxedrtjymuq5lfrskk2itnniyfa5gdvqp5sjoeeb33oi2e"), + "cron": MustParseCid("bafk2bzaceb3nfsu5jbftadzxy24caz4tlgi6476yml25tfq2g7higtgnifys4"), + "datacap": MustParseCid("bafk2bzacec3s7oovwjxdx3hnhtqr75fsvhj7p4545gedt3kf2iuaw7zqhym2c"), + "eam": MustParseCid("bafk2bzacebw4ye6kvufarvrtqebs57idw6ydtzli7egd4h2t33jwoi547trra"), + "ethaccount": MustParseCid("bafk2bzaceavrimh4mcla6zi25uhs3ystix2n5rp4kfqeiewkh337zpjbo3egq"), + "evm": MustParseCid("bafk2bzacecnsk2ydh2q6wxf2fzsvivo6cfrka3jos62io2ds2xou4gl2byqvw"), + "init": MustParseCid("bafk2bzacebb3l4gw6hfszizw5zwho3pfpnmgrmxqm4ie42dgn62325lo4vwc2"), + "multisig": MustParseCid("bafk2bzacedi6ii3ewygygjukn4viros3uiztonnf6tg6b3ppqk4pdtqrwgeuw"), + "paymentchannel": MustParseCid("bafk2bzacebwqqfhodha2jl7tbws3dpy2dkngepbllqx6hy72zdokui3ow6eeq"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzacedbeexrv2d4kiridcvqgdatcwo2an4xsmg3ckdrptxu6c3y7mm6ji"), + "storagemarket": MustParseCid("bafk2bzacedalaigmokrtimabt7y7bkok5nd2j5gmifdahht3dsz5ulj7vxdgu"), + "storageminer": MustParseCid("bafk2bzacecpq5wjp3frz3b4cd2pozegi7sykgcawnaowjm6ddyai2epbphxvw"), + "storagepower": MustParseCid("bafk2bzacedfxlpyj5uxlh5uuhl55lazmhm7q6pr3qoywxb25qrytbptpy7zb6"), + "system": MustParseCid("bafk2bzacecbscw26oyfgdse6y6ij5fqtaq5uo2ehfom26mle4rk4ann2xf2jq"), + "verifiedregistry": MustParseCid("bafk2bzaceanpda37bvefmzfemikyokwnspzxdxqz5kriaqex4hpevdhphu6sq"), + }, +}, { + Network: "testing", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacedkjpqx27wgsvfxzuxfvixuxtbpt2y6yo6igcasez6gqiowron776"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), @@ -525,8 +688,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacectzxvtoselhnzsair5nv6k5vokvegnht6z2lfee4p3xexo4kg4m6"), }, }, { - Network: "testing", - Version: 9, + Network: "testing", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacecnnrmekqw2xvud46g3vo6x26cogh3ydgljqajlxqxzzbuxsjlwjm"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), @@ -543,8 +707,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceatmqip2o3ausbntvdhj7yemu6hb3b5yqv6hm42gylbbmz7geocpm"), }, }, { - Network: "testing", - Version: 10, + Network: "testing", + Version: 10, + ManifestCid: MustParseCid("bafy2bzacearh2dy6uzcfvruckai5qbf7banklkg6uezaa7w6onsmdfxn2qxbs"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"), @@ -565,8 +730,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"), }, }, { - Network: "testing", - Version: 11, + Network: "testing", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacea7tbn4p232ecrjvlp2uvpci5pexqjqq2vpv4t5ihktpja2zsj3ek"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"), @@ -587,8 +753,32 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"), }, }, { - Network: "testing-fake-proofs", - Version: 8, + Network: "testing", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzacedjgfy7dmbd4i3io5r47eokprndhucdvwaxqyw4ijhhtldhewojk4"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"), + "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"), + "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"), + "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"), + "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"), + "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"), + "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"), + "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"), + "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"), + "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"), + "storageminer": MustParseCid("bafk2bzacednqbtebg7xxsr2sle42pfxmz5chxn32bsjssgc3mzt7iw2eevaly"), + "storagepower": MustParseCid("bafk2bzacebovido4zxtywaz32ejagvtk4v7z5w5nwxrflaldsf56xd7pecu4w"), + "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"), + "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"), + }, +}, { + Network: "testing-fake-proofs", + Version: 8, + ManifestCid: MustParseCid("bafy2bzacecd3lb5v6tzjylnhnrhexslssyaozy6hogzgpkhztoe76exbrgrug"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzacebmfbtdj5vruje5auacrhhprcjdd6uclhukb7je7t2f6ozfcgqlu2"), @@ -604,8 +794,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacectzxvtoselhnzsair5nv6k5vokvegnht6z2lfee4p3xexo4kg4m6"), }, }, { - Network: "testing-fake-proofs", - Version: 9, + Network: "testing-fake-proofs", + Version: 9, + ManifestCid: MustParseCid("bafy2bzacecql2gj2tri4fnbznmldue73qzt6zszvugw4exd64mwb52zrhv7k2"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceaiebfiuu76zoywzltelio2zuvsavirka27ur6kspn7scvcl5cuiy"), @@ -622,8 +813,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzaceatmqip2o3ausbntvdhj7yemu6hb3b5yqv6hm42gylbbmz7geocpm"), }, }, { - Network: "testing-fake-proofs", - Version: 10, + Network: "testing-fake-proofs", + Version: 10, + ManifestCid: MustParseCid("bafy2bzacedw6kk3u2vjexzqmm3vtvusd42lllk7wbnsrlxxmt35smsnmiatca"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"), @@ -644,8 +836,9 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"), }, }, { - Network: "testing-fake-proofs", - Version: 11, + Network: "testing-fake-proofs", + Version: 11, + ManifestCid: MustParseCid("bafy2bzacecyqfyzmw72234rvbk6vzq2omnmt3cbfezkq2h3ewnn33w42b2s62"), Actors: map[string]cid.Cid{ "account": MustParseCid("bafk2bzaceds3iy5qjgr3stoywxt4uxvhybca23q7d2kxhitedgudrkhxaxa6o"), @@ -665,4 +858,27 @@ var EmbeddedBuiltinActorsMetadata []*BuiltinActorsMetadata = []*BuiltinActorsMet "system": MustParseCid("bafk2bzaceaafqf7lwaiqx5po6b3l4dfg4xsr5qhfk3bjgoi7qke2mfy3shla4"), "verifiedregistry": MustParseCid("bafk2bzacec2ouguts4z335vetmdeifpk5fkqthcmrwshk7yxbw2uohddfu5lo"), }, +}, { + Network: "testing-fake-proofs", + Version: 12, + + ManifestCid: MustParseCid("bafy2bzaceblvi7d3yosakpuux27gqzr34gcjr6a2f6uzbyagmwybgfsk4xeu2"), + Actors: map[string]cid.Cid{ + "account": MustParseCid("bafk2bzacedhme5nkedu2x3vwwfakrs4zwqrbdcb7epevety7peisq4bcahyke"), + "cron": MustParseCid("bafk2bzaced5ky3x7w6naz45tsx4omkfztyy4flmr72hfr725ksrxdhvzuulwm"), + "datacap": MustParseCid("bafk2bzacedlhpgrdwzyfhcywoud5n5gwx2arwmyqvg7yogmrpt7h5gfmotjpc"), + "eam": MustParseCid("bafk2bzaceb754ghlrlmiqref2snlqsgvmpmg3tsjokok6eshh4pt4guv64zg4"), + "ethaccount": MustParseCid("bafk2bzaceaa5vdnlqdbf5tamzxvmuva3e5zfvy5vycw4gem2b6hmintnx6ye4"), + "evm": MustParseCid("bafk2bzaceaq5fequmt5jeuixw3qn6exx4atcpveugvblpz5oacy2xnypz2mww"), + "init": MustParseCid("bafk2bzaced275afmy4htdxsgff557owyteyl32vrntbdeemzqf3qkw22n6n4u"), + "multisig": MustParseCid("bafk2bzacebiao7jb3c7svwcphkdvixj6z3genj5ufwtattmp3cmelhqinq4na"), + "paymentchannel": MustParseCid("bafk2bzacecjuud657ydp5fwlbeiqzknzkqcrqh4d5huunmtubhas55fsj3n4k"), + "placeholder": MustParseCid("bafk2bzacedfvut2myeleyq67fljcrw4kkmn5pb5dpyozovj7jpoez5irnc3ro"), + "reward": MustParseCid("bafk2bzaceae7eic2i2cmpxmkssezmutfc635tyzxxsmnu6ctnvkd33akrpipq"), + "storagemarket": MustParseCid("bafk2bzaceaj36pbc7sxzdelygq4ew3n2w3l5y442ogvznw3mw54fxafavjcru"), + "storageminer": MustParseCid("bafk2bzaceaoaduzssj46mse6gizcy764ingsgvuavafkowf4vexluindct3ji"), + "storagepower": MustParseCid("bafk2bzacedqvicpfdcegfsj6p4rb3judx7v5v6trpnca7djbim4pts5appis4"), + "system": MustParseCid("bafk2bzacecxbbatjxkfjm5f27esjghqe2o5ajmcalp4rbqq5vtxdmpq4ylmb2"), + "verifiedregistry": MustParseCid("bafk2bzacecwzauoon6sngmiiv4ppoxshirgzyfssfircvampxjkv673vlim6m"), + }, }} diff --git a/build/openrpc/full.json.gz b/build/openrpc/full.json.gz index f5d6f6747..eaabc58de 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 dac0e82fc..530198113 100644 Binary files a/build/openrpc/gateway.json.gz and b/build/openrpc/gateway.json.gz differ diff --git a/build/openrpc/miner.json.gz b/build/openrpc/miner.json.gz index be2151d62..51b4f75ca 100644 Binary files a/build/openrpc/miner.json.gz and b/build/openrpc/miner.json.gz differ diff --git a/build/params_2k.go b/build/params_2k.go index b6b09bb2e..4fb4df183 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -63,6 +63,8 @@ var UpgradeHyggeHeight = abi.ChainEpoch(30) var UpgradeHyperspaceNV19Height = abi.ChainEpoch(60) +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(120) + var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } diff --git a/build/params_butterfly.go b/build/params_butterfly.go index 442d604cc..9e77bfd90 100644 --- a/build/params_butterfly.go +++ b/build/params_butterfly.go @@ -51,9 +51,11 @@ const UpgradeChocolateHeight = -17 const UpgradeOhSnapHeight = -18 const UpgradeSkyrHeight = -19 const UpgradeSharkHeight = abi.ChainEpoch(-20) -const UpgradeHyggeHeight = abi.ChainEpoch(600) +const UpgradeHyggeHeight = abi.ChainEpoch(80) -var UpgradeHyperspaceNV19Height = abi.ChainEpoch(99999999999999) +var UpgradeHyperspaceNV19Height = abi.ChainEpoch(100) + +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(120) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg512MiBV1, diff --git a/build/params_calibnet.go b/build/params_calibnet.go index 729ad1207..4b3ae329f 100644 --- a/build/params_calibnet.go +++ b/build/params_calibnet.go @@ -73,7 +73,11 @@ const UpgradeSharkHeight = 16800 // 6 days after genesis const UpgradeHyggeHeight = math.MaxInt64 -var UpgradeHyperspaceNV19Height = abi.ChainEpoch(99999999999999) +// dummy +var UpgradeHyperspaceNV19Height = abi.ChainEpoch(math.MaxInt64 - 1) + +// dummy +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(math.MaxInt64) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg32GiBV1, diff --git a/build/params_hyperspace.go b/build/params_hyperspace.go index 5fa7b8f28..bc24e891f 100644 --- a/build/params_hyperspace.go +++ b/build/params_hyperspace.go @@ -58,6 +58,9 @@ var UpgradeHyggeHeight = abi.ChainEpoch(-21) // 2023-01-18T15:00:00Z var UpgradeHyperspaceNV19Height = abi.ChainEpoch(6840) +// 2023-02-15T15:00:00Z +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(87480) + var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, } diff --git a/build/params_interop.go b/build/params_interop.go index 36776f4b7..1c2ad61e2 100644 --- a/build/params_interop.go +++ b/build/params_interop.go @@ -4,6 +4,7 @@ package build import ( + "math" "os" "strconv" @@ -52,9 +53,11 @@ var UpgradeSkyrHeight = abi.ChainEpoch(-19) const UpgradeSharkHeight = abi.ChainEpoch(-20) -const UpgradeHyggeHeight = abi.ChainEpoch(99999999999999) +const UpgradeHyggeHeight = abi.ChainEpoch(math.MaxInt64 - 2) -var UpgradeHyperspaceNV19Height = abi.ChainEpoch(99999999999999) +var UpgradeHyperspaceNV19Height = abi.ChainEpoch(math.MaxInt64 - 1) + +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(math.MaxInt64) var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ 0: DrandMainnet, diff --git a/build/params_mainnet.go b/build/params_mainnet.go index bad165187..35561a281 100644 --- a/build/params_mainnet.go +++ b/build/params_mainnet.go @@ -87,10 +87,13 @@ const UpgradeSkyrHeight = 1960320 const UpgradeSharkHeight = 2383680 // ?????????????? -var UpgradeHyggeHeight = abi.ChainEpoch(math.MaxInt64 - 1) +var UpgradeHyggeHeight = abi.ChainEpoch(math.MaxInt64 - 2) // ?????????????? -var UpgradeHyperspaceNV19Height = abi.ChainEpoch(math.MaxInt64) +var UpgradeHyperspaceNV19Height = abi.ChainEpoch(math.MaxInt64 - 1) + +// dummy +var UpgradeHyperspaceNV20Height = abi.ChainEpoch(math.MaxInt64) var SupportedProofTypes = []abi.RegisteredSealProof{ abi.RegisteredSealProof_StackedDrg32GiBV1, diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 6d9c2279f..6e2e6d8fb 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -33,7 +33,7 @@ const TestNetworkVersion = network.Version{{.latestNetworkVersion}} /* inline-gen start */ -const TestNetworkVersion = network.Version19 +const TestNetworkVersion = network.Version20 /* inline-gen end */ diff --git a/chain/actors/builtin/account/account.go b/chain/actors/builtin/account/account.go index a29248d56..dcb60f801 100644 --- a/chain/actors/builtin/account/account.go +++ b/chain/actors/builtin/account/account.go @@ -6,7 +6,7 @@ import ( "github.com/filecoin-project/go-address" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -22,7 +22,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -var Methods = builtin11.MethodsAccount +var Methods = builtin12.MethodsAccount func Load(store adt.Store, act *types.Actor) (State, error) { if name, av, ok := actors.GetActorMetaByCode(act.Code); ok { @@ -44,6 +44,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -111,6 +114,9 @@ func MakeState(store adt.Store, av actorstypes.Version, addr address.Address) (S case actorstypes.Version11: return make11(store, addr) + case actorstypes.Version12: + return make12(store, addr) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -139,5 +145,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/account/v12.go b/chain/actors/builtin/account/v12.go new file mode 100644 index 000000000..af2c4186f --- /dev/null +++ b/chain/actors/builtin/account/v12.go @@ -0,0 +1,62 @@ +package account + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + actorstypes "github.com/filecoin-project/go-state-types/actors" + account12 "github.com/filecoin-project/go-state-types/builtin/v12/account" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, addr address.Address) (State, error) { + out := state12{store: store} + out.State = account12.State{Address: addr} + return &out, nil +} + +type state12 struct { + account12.State + store adt.Store +} + +func (s *state12) PubkeyAddress() (address.Address, error) { + return s.Address, nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ActorKey() string { + return manifest.AccountKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/cron/cron.go b/chain/actors/builtin/cron/cron.go index c2f758698..17b291788 100644 --- a/chain/actors/builtin/cron/cron.go +++ b/chain/actors/builtin/cron/cron.go @@ -5,7 +5,7 @@ import ( "golang.org/x/xerrors" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" @@ -40,6 +40,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -107,13 +110,16 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version11: return make11(store) + case actorstypes.Version12: + return make12(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } var ( - Address = builtin11.CronActorAddr - Methods = builtin11.MethodsCron + Address = builtin12.CronActorAddr + Methods = builtin12.MethodsCron ) type State interface { @@ -137,5 +143,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/cron/v12.go b/chain/actors/builtin/cron/v12.go new file mode 100644 index 000000000..44f018d68 --- /dev/null +++ b/chain/actors/builtin/cron/v12.go @@ -0,0 +1,57 @@ +package cron + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + cron12 "github.com/filecoin-project/go-state-types/builtin/v12/cron" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store) (State, error) { + out := state12{store: store} + out.State = *cron12.ConstructState(cron12.BuiltInEntries()) + return &out, nil +} + +type state12 struct { + cron12.State + store adt.Store +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ActorKey() string { + return manifest.CronKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/datacap/datacap.go b/chain/actors/builtin/datacap/datacap.go index 3cf557e6c..0c8f04bbf 100644 --- a/chain/actors/builtin/datacap/datacap.go +++ b/chain/actors/builtin/datacap/datacap.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" @@ -17,8 +17,8 @@ import ( ) var ( - Address = builtin11.DatacapActorAddr - Methods = builtin11.MethodsDatacap + Address = builtin12.DatacapActorAddr + Methods = builtin12.MethodsDatacap ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -38,6 +38,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -56,6 +59,9 @@ func MakeState(store adt.Store, av actorstypes.Version, governor address.Address case actorstypes.Version11: return make11(store, governor, bitwidth) + case actorstypes.Version12: + return make12(store, governor, bitwidth) + default: return nil, xerrors.Errorf("datacap actor only valid for actors v9 and above, got %d", av) } @@ -79,5 +85,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/datacap/v12.go b/chain/actors/builtin/datacap/v12.go new file mode 100644 index 000000000..91563a2b6 --- /dev/null +++ b/chain/actors/builtin/datacap/v12.go @@ -0,0 +1,82 @@ +package datacap + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + datacap12 "github.com/filecoin-project/go-state-types/builtin/v12/datacap" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, governor address.Address, bitwidth uint64) (State, error) { + out := state12{store: store} + s, err := datacap12.ConstructState(store, governor, bitwidth) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + datacap12.State + store adt.Store +} + +func (s *state12) Governor() (address.Address, error) { + return s.State.Governor, nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachClient(s.store, actors.Version12, s.verifiedClients, cb) +} + +func (s *state12) verifiedClients() (adt.Map, error) { + return adt12.AsMap(s.store, s.Token.Balances, int(s.Token.HamtBitWidth)) +} + +func (s *state12) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version12, s.verifiedClients, addr) +} + +func (s *state12) ActorKey() string { + return manifest.DatacapKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/evm/evm.go b/chain/actors/builtin/evm/evm.go index 20ce5e0d4..24315cf75 100644 --- a/chain/actors/builtin/evm/evm.go +++ b/chain/actors/builtin/evm/evm.go @@ -5,7 +5,7 @@ import ( "golang.org/x/xerrors" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" @@ -14,7 +14,7 @@ import ( "github.com/filecoin-project/lotus/chain/types" ) -var Methods = builtin11.MethodsEVM +var Methods = builtin12.MethodsEVM func Load(store adt.Store, act *types.Actor) (State, error) { if name, av, ok := actors.GetActorMetaByCode(act.Code); ok { @@ -30,6 +30,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -45,6 +48,9 @@ func MakeState(store adt.Store, av actorstypes.Version, bytecode cid.Cid) (State case actorstypes.Version11: return make11(store, bytecode) + case actorstypes.Version12: + return make12(store, bytecode) + default: return nil, xerrors.Errorf("evm actor only valid for actors v10 and above, got %d", av) } diff --git a/chain/actors/builtin/evm/v11.go b/chain/actors/builtin/evm/v11.go index 16238b0da..fca095ee2 100644 --- a/chain/actors/builtin/evm/v11.go +++ b/chain/actors/builtin/evm/v11.go @@ -3,6 +3,7 @@ package evm import ( "github.com/ipfs/go-cid" + "github.com/filecoin-project/go-state-types/abi" evm11 "github.com/filecoin-project/go-state-types/builtin/v11/evm" "github.com/filecoin-project/lotus/chain/actors/adt" @@ -43,3 +44,25 @@ func (s *state11) Nonce() (uint64, error) { func (s *state11) GetState() interface{} { return &s.State } + +func (s *state11) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state11) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state11) 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/v12.go b/chain/actors/builtin/evm/v12.go new file mode 100644 index 000000000..821f4bee0 --- /dev/null +++ b/chain/actors/builtin/evm/v12.go @@ -0,0 +1,68 @@ +package evm + +import ( + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/abi" + evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm" + + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, bytecode cid.Cid) (State, error) { + out := state12{store: store} + s, err := evm12.ConstructState(store, bytecode) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + evm12.State + store adt.Store +} + +func (s *state12) Nonce() (uint64, error) { + return s.State.Nonce, nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) GetBytecodeCID() (cid.Cid, error) { + return s.State.Bytecode, nil +} + +func (s *state12) GetBytecodeHash() ([32]byte, error) { + return s.State.BytecodeHash, nil +} + +func (s *state12) 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/init/init.go b/chain/actors/builtin/init/init.go index 2d9e41275..41a763ecf 100644 --- a/chain/actors/builtin/init/init.go +++ b/chain/actors/builtin/init/init.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -25,8 +25,8 @@ import ( ) var ( - Address = builtin11.InitActorAddr - Methods = builtin11.MethodsInit + Address = builtin12.InitActorAddr + Methods = builtin12.MethodsInit ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, networkName string) (Sta case actorstypes.Version11: return make11(store, networkName) + case actorstypes.Version12: + return make12(store, networkName) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -167,5 +173,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/init/v12.go b/chain/actors/builtin/init/v12.go new file mode 100644 index 000000000..3eab7a740 --- /dev/null +++ b/chain/actors/builtin/init/v12.go @@ -0,0 +1,147 @@ +package init + +import ( + "crypto/sha256" + "fmt" + + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/node/modules/dtypes" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, networkName string) (State, error) { + out := state12{store: store} + + s, err := init12.ConstructState(store, networkName) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + init12.State + store adt.Store +} + +func (s *state12) ResolveAddress(address address.Address) (address.Address, bool, error) { + return s.State.ResolveAddress(s.store, address) +} + +func (s *state12) MapAddressToNewID(address address.Address) (address.Address, error) { + return s.State.MapAddressToNewID(s.store, address) +} + +func (s *state12) ForEachActor(cb func(id abi.ActorID, address address.Address) error) error { + addrs, err := adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth) + if err != nil { + return err + } + var actorID cbg.CborInt + return addrs.ForEach(&actorID, func(key string) error { + addr, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(abi.ActorID(actorID), addr) + }) +} + +func (s *state12) NetworkName() (dtypes.NetworkName, error) { + return dtypes.NetworkName(s.State.NetworkName), nil +} + +func (s *state12) SetNetworkName(name string) error { + s.State.NetworkName = name + return nil +} + +func (s *state12) SetNextID(id abi.ActorID) error { + s.State.NextID = id + return nil +} + +func (s *state12) Remove(addrs ...address.Address) (err error) { + m, err := adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth) + if err != nil { + return err + } + for _, addr := range addrs { + if err = m.Delete(abi.AddrKey(addr)); err != nil { + return xerrors.Errorf("failed to delete entry for address: %s; err: %w", addr, err) + } + } + amr, err := m.Root() + if err != nil { + return xerrors.Errorf("failed to get address map root: %w", err) + } + s.State.AddressMap = amr + return nil +} + +func (s *state12) SetAddressMap(mcid cid.Cid) error { + s.State.AddressMap = mcid + return nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) AddressMap() (adt.Map, error) { + return adt12.AsMap(s.store, s.State.AddressMap, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) AddressMapBitWidth() int { + return builtin12.DefaultHamtBitwidth +} + +func (s *state12) AddressMapHashFunction() func(input []byte) []byte { + return func(input []byte) []byte { + res := sha256.Sum256(input) + return res[:] + } +} + +func (s *state12) ActorKey() string { + return manifest.InitKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/market/market.go b/chain/actors/builtin/market/market.go index 36936e787..39473d560 100644 --- a/chain/actors/builtin/market/market.go +++ b/chain/actors/builtin/market/market.go @@ -55,6 +55,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -122,6 +125,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version11: return make11(store) + case actorstypes.Version12: + return make12(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -217,6 +223,9 @@ func DecodePublishStorageDealsReturn(b []byte, nv network.Version) (PublishStora case actorstypes.Version11: return decodePublishStorageDealsReturn11(b) + case actorstypes.Version12: + return decodePublishStorageDealsReturn12(b) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -303,5 +312,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/market/v12.go b/chain/actors/builtin/market/v12.go new file mode 100644 index 000000000..3532fc4f4 --- /dev/null +++ b/chain/actors/builtin/market/v12.go @@ -0,0 +1,377 @@ +package market + +import ( + "bytes" + "fmt" + + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-bitfield" + rlepluslazy "github.com/filecoin-project/go-bitfield/rle" + "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" + market12 "github.com/filecoin-project/go-state-types/builtin/v12/market" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + markettypes "github.com/filecoin-project/go-state-types/builtin/v9/market" + verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/types" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store) (State, error) { + out := state12{store: store} + + s, err := market12.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + market12.State + store adt.Store +} + +func (s *state12) TotalLocked() (abi.TokenAmount, error) { + fml := types.BigAdd(s.TotalClientLockedCollateral, s.TotalProviderLockedCollateral) + fml = types.BigAdd(fml, s.TotalClientStorageFee) + return fml, nil +} + +func (s *state12) BalancesChanged(otherState State) (bool, error) { + otherState12, ok := otherState.(*state12) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.EscrowTable.Equals(otherState12.State.EscrowTable) || !s.State.LockedTable.Equals(otherState12.State.LockedTable), nil +} + +func (s *state12) StatesChanged(otherState State) (bool, error) { + otherState12, ok := otherState.(*state12) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.States.Equals(otherState12.State.States), nil +} + +func (s *state12) States() (DealStates, error) { + stateArray, err := adt12.AsArray(s.store, s.State.States, market12.StatesAmtBitwidth) + if err != nil { + return nil, err + } + return &dealStates12{stateArray}, nil +} + +func (s *state12) ProposalsChanged(otherState State) (bool, error) { + otherState12, ok := otherState.(*state12) + if !ok { + // there's no way to compare different versions of the state, so let's + // just say that means the state of balances has changed + return true, nil + } + return !s.State.Proposals.Equals(otherState12.State.Proposals), nil +} + +func (s *state12) Proposals() (DealProposals, error) { + proposalArray, err := adt12.AsArray(s.store, s.State.Proposals, market12.ProposalsAmtBitwidth) + if err != nil { + return nil, err + } + return &dealProposals12{proposalArray}, nil +} + +func (s *state12) EscrowTable() (BalanceTable, error) { + bt, err := adt12.AsBalanceTable(s.store, s.State.EscrowTable) + if err != nil { + return nil, err + } + return &balanceTable12{bt}, nil +} + +func (s *state12) LockedTable() (BalanceTable, error) { + bt, err := adt12.AsBalanceTable(s.store, s.State.LockedTable) + if err != nil { + return nil, err + } + return &balanceTable12{bt}, nil +} + +func (s *state12) VerifyDealsForActivation( + minerAddr address.Address, deals []abi.DealID, currEpoch, sectorExpiry abi.ChainEpoch, +) (weight, verifiedWeight abi.DealWeight, err error) { + w, vw, _, err := market12.ValidateDealsForActivation(&s.State, s.store, deals, minerAddr, sectorExpiry, currEpoch) + return w, vw, err +} + +func (s *state12) NextID() (abi.DealID, error) { + return s.State.NextID, nil +} + +type balanceTable12 struct { + *adt12.BalanceTable +} + +func (bt *balanceTable12) ForEach(cb func(address.Address, abi.TokenAmount) error) error { + asMap := (*adt12.Map)(bt.BalanceTable) + var ta abi.TokenAmount + return asMap.ForEach(&ta, func(key string) error { + a, err := address.NewFromBytes([]byte(key)) + if err != nil { + return err + } + return cb(a, ta) + }) +} + +type dealStates12 struct { + adt.Array +} + +func (s *dealStates12) Get(dealID abi.DealID) (*DealState, bool, error) { + var deal12 market12.DealState + found, err := s.Array.Get(uint64(dealID), &deal12) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + deal := fromV12DealState(deal12) + return &deal, true, nil +} + +func (s *dealStates12) ForEach(cb func(dealID abi.DealID, ds DealState) error) error { + var ds12 market12.DealState + return s.Array.ForEach(&ds12, func(idx int64) error { + return cb(abi.DealID(idx), fromV12DealState(ds12)) + }) +} + +func (s *dealStates12) decode(val *cbg.Deferred) (*DealState, error) { + var ds12 market12.DealState + if err := ds12.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + ds := fromV12DealState(ds12) + return &ds, nil +} + +func (s *dealStates12) array() adt.Array { + return s.Array +} + +func fromV12DealState(v12 market12.DealState) DealState { + ret := DealState{ + SectorStartEpoch: v12.SectorStartEpoch, + LastUpdatedEpoch: v12.LastUpdatedEpoch, + SlashEpoch: v12.SlashEpoch, + VerifiedClaim: 0, + } + + ret.VerifiedClaim = verifregtypes.AllocationId(v12.VerifiedClaim) + + return ret +} + +type dealProposals12 struct { + adt.Array +} + +func (s *dealProposals12) Get(dealID abi.DealID) (*DealProposal, bool, error) { + var proposal12 market12.DealProposal + found, err := s.Array.Get(uint64(dealID), &proposal12) + if err != nil { + return nil, false, err + } + if !found { + return nil, false, nil + } + + proposal, err := fromV12DealProposal(proposal12) + if err != nil { + return nil, true, xerrors.Errorf("decoding proposal: %w", err) + } + + return &proposal, true, nil +} + +func (s *dealProposals12) ForEach(cb func(dealID abi.DealID, dp DealProposal) error) error { + var dp12 market12.DealProposal + return s.Array.ForEach(&dp12, func(idx int64) error { + dp, err := fromV12DealProposal(dp12) + if err != nil { + return xerrors.Errorf("decoding proposal: %w", err) + } + + return cb(abi.DealID(idx), dp) + }) +} + +func (s *dealProposals12) decode(val *cbg.Deferred) (*DealProposal, error) { + var dp12 market12.DealProposal + if err := dp12.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return nil, err + } + + dp, err := fromV12DealProposal(dp12) + if err != nil { + return nil, err + } + + return &dp, nil +} + +func (s *dealProposals12) array() adt.Array { + return s.Array +} + +func fromV12DealProposal(v12 market12.DealProposal) (DealProposal, error) { + + label, err := fromV12Label(v12.Label) + + if err != nil { + return DealProposal{}, xerrors.Errorf("error setting deal label: %w", err) + } + + return DealProposal{ + PieceCID: v12.PieceCID, + PieceSize: v12.PieceSize, + VerifiedDeal: v12.VerifiedDeal, + Client: v12.Client, + Provider: v12.Provider, + + Label: label, + + StartEpoch: v12.StartEpoch, + EndEpoch: v12.EndEpoch, + StoragePricePerEpoch: v12.StoragePricePerEpoch, + + ProviderCollateral: v12.ProviderCollateral, + ClientCollateral: v12.ClientCollateral, + }, nil +} + +func fromV12Label(v12 market12.DealLabel) (DealLabel, error) { + if v12.IsString() { + str, err := v12.ToString() + if err != nil { + return markettypes.EmptyDealLabel, xerrors.Errorf("failed to convert string label to string: %w", err) + } + return markettypes.NewLabelFromString(str) + } + + bs, err := v12.ToBytes() + if err != nil { + return markettypes.EmptyDealLabel, xerrors.Errorf("failed to convert bytes label to bytes: %w", err) + } + return markettypes.NewLabelFromBytes(bs) +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +var _ PublishStorageDealsReturn = (*publishStorageDealsReturn12)(nil) + +func decodePublishStorageDealsReturn12(b []byte) (PublishStorageDealsReturn, error) { + var retval market12.PublishStorageDealsReturn + if err := retval.UnmarshalCBOR(bytes.NewReader(b)); err != nil { + return nil, xerrors.Errorf("failed to unmarshal PublishStorageDealsReturn: %w", err) + } + + return &publishStorageDealsReturn12{retval}, nil +} + +type publishStorageDealsReturn12 struct { + market12.PublishStorageDealsReturn +} + +func (r *publishStorageDealsReturn12) IsDealValid(index uint64) (bool, int, error) { + + set, err := r.ValidDeals.IsSet(index) + if err != nil || !set { + return false, -1, err + } + maskBf, err := bitfield.NewFromIter(&rlepluslazy.RunSliceIterator{ + Runs: []rlepluslazy.Run{rlepluslazy.Run{Val: true, Len: index}}}) + if err != nil { + return false, -1, err + } + before, err := bitfield.IntersectBitField(maskBf, r.ValidDeals) + if err != nil { + return false, -1, err + } + outIdx, err := before.Count() + if err != nil { + return false, -1, err + } + return set, int(outIdx), nil + +} + +func (r *publishStorageDealsReturn12) DealIDs() ([]abi.DealID, error) { + return r.IDs, nil +} + +func (s *state12) GetAllocationIdForPendingDeal(dealId abi.DealID) (verifregtypes.AllocationId, error) { + + allocations, err := adt12.AsMap(s.store, s.PendingDealAllocationIds, builtin.DefaultHamtBitwidth) + if err != nil { + return verifregtypes.NoAllocationID, xerrors.Errorf("failed to load allocation id for %d: %w", dealId, err) + } + + var allocationId cbg.CborInt + found, err := allocations.Get(abi.UIntKey(uint64(dealId)), &allocationId) + if err != nil { + return verifregtypes.NoAllocationID, xerrors.Errorf("failed to load allocation id for %d: %w", dealId, err) + } + if !found { + return verifregtypes.NoAllocationID, nil + } + + return verifregtypes.AllocationId(allocationId), nil + +} + +func (s *state12) ActorKey() string { + return manifest.MarketKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/miner/miner.go b/chain/actors/builtin/miner/miner.go index 3421f2c8d..d2ae301fb 100644 --- a/chain/actors/builtin/miner/miner.go +++ b/chain/actors/builtin/miner/miner.go @@ -48,6 +48,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -115,6 +118,9 @@ func MakeState(store adt.Store, av actors.Version) (State, error) { case actors.Version11: return make11(store) + case actors.Version12: + return make12(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -321,5 +327,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/miner/v12.go b/chain/actors/builtin/miner/v12.go new file mode 100644 index 000000000..787da7d0f --- /dev/null +++ b/chain/actors/builtin/miner/v12.go @@ -0,0 +1,591 @@ +package miner + +import ( + "bytes" + "errors" + "fmt" + + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-bitfield" + rle "github.com/filecoin-project/go-bitfield/rle" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store) (State, error) { + out := state12{store: store} + out.State = miner12.State{} + return &out, nil +} + +type state12 struct { + miner12.State + store adt.Store +} + +type deadline12 struct { + miner12.Deadline + store adt.Store +} + +type partition12 struct { + miner12.Partition + store adt.Store +} + +func (s *state12) AvailableBalance(bal abi.TokenAmount) (available abi.TokenAmount, err error) { + defer func() { + if r := recover(); r != nil { + err = xerrors.Errorf("failed to get available balance: %w", r) + available = abi.NewTokenAmount(0) + } + }() + // this panics if the miner doesnt have enough funds to cover their locked pledge + available, err = s.GetAvailableBalance(bal) + return available, err +} + +func (s *state12) VestedFunds(epoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.CheckVestedFunds(s.store, epoch) +} + +func (s *state12) LockedFunds() (LockedFunds, error) { + return LockedFunds{ + VestingFunds: s.State.LockedFunds, + InitialPledgeRequirement: s.State.InitialPledge, + PreCommitDeposits: s.State.PreCommitDeposits, + }, nil +} + +func (s *state12) FeeDebt() (abi.TokenAmount, error) { + return s.State.FeeDebt, nil +} + +func (s *state12) InitialPledge() (abi.TokenAmount, error) { + return s.State.InitialPledge, nil +} + +func (s *state12) PreCommitDeposits() (abi.TokenAmount, error) { + return s.State.PreCommitDeposits, nil +} + +// Returns nil, nil if sector is not found +func (s *state12) GetSector(num abi.SectorNumber) (*SectorOnChainInfo, error) { + info, ok, err := s.State.GetSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV12SectorOnChainInfo(*info) + return &ret, nil +} + +func (s *state12) FindSector(num abi.SectorNumber) (*SectorLocation, error) { + dlIdx, partIdx, err := s.State.FindSector(s.store, num) + if err != nil { + return nil, err + } + return &SectorLocation{ + Deadline: dlIdx, + Partition: partIdx, + }, nil +} + +func (s *state12) NumLiveSectors() (uint64, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return 0, err + } + var total uint64 + if err := dls.ForEach(s.store, func(dlIdx uint64, dl *miner12.Deadline) error { + total += dl.LiveSectors + return nil + }); err != nil { + return 0, err + } + return total, nil +} + +// GetSectorExpiration returns the effective expiration of the given sector. +// +// If the sector does not expire early, the Early expiration field is 0. +func (s *state12) GetSectorExpiration(num abi.SectorNumber) (*SectorExpiration, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + // NOTE: this can be optimized significantly. + // 1. If the sector is non-faulty, it will expire on-time (can be + // learned from the sector info). + // 2. If it's faulty, it will expire early within the first 42 entries + // of the expiration queue. + + stopErr := errors.New("stop") + out := SectorExpiration{} + err = dls.ForEach(s.store, func(dlIdx uint64, dl *miner12.Deadline) error { + partitions, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + quant := s.State.QuantSpecForDeadline(dlIdx) + var part miner12.Partition + return partitions.ForEach(&part, func(partIdx int64) error { + if found, err := part.Sectors.IsSet(uint64(num)); err != nil { + return err + } else if !found { + return nil + } + if found, err := part.Terminated.IsSet(uint64(num)); err != nil { + return err + } else if found { + // already terminated + return stopErr + } + + q, err := miner12.LoadExpirationQueue(s.store, part.ExpirationsEpochs, quant, miner12.PartitionExpirationAmtBitwidth) + if err != nil { + return err + } + var exp miner12.ExpirationSet + return q.ForEach(&exp, func(epoch int64) error { + if early, err := exp.EarlySectors.IsSet(uint64(num)); err != nil { + return err + } else if early { + out.Early = abi.ChainEpoch(epoch) + return nil + } + if onTime, err := exp.OnTimeSectors.IsSet(uint64(num)); err != nil { + return err + } else if onTime { + out.OnTime = abi.ChainEpoch(epoch) + return stopErr + } + return nil + }) + }) + }) + if err == stopErr { + err = nil + } + if err != nil { + return nil, err + } + if out.Early == 0 && out.OnTime == 0 { + return nil, xerrors.Errorf("failed to find sector %d", num) + } + return &out, nil +} + +func (s *state12) GetPrecommittedSector(num abi.SectorNumber) (*SectorPreCommitOnChainInfo, error) { + info, ok, err := s.State.GetPrecommittedSector(s.store, num) + if !ok || err != nil { + return nil, err + } + + ret := fromV12SectorPreCommitOnChainInfo(*info) + + return &ret, nil +} + +func (s *state12) ForEachPrecommittedSector(cb func(SectorPreCommitOnChainInfo) error) error { + precommitted, err := adt12.AsMap(s.store, s.State.PreCommittedSectors, builtin12.DefaultHamtBitwidth) + if err != nil { + return err + } + + var info miner12.SectorPreCommitOnChainInfo + if err := precommitted.ForEach(&info, func(_ string) error { + return cb(fromV12SectorPreCommitOnChainInfo(info)) + }); err != nil { + return err + } + + return nil +} + +func (s *state12) LoadSectors(snos *bitfield.BitField) ([]*SectorOnChainInfo, error) { + sectors, err := miner12.LoadSectors(s.store, s.State.Sectors) + if err != nil { + return nil, err + } + + // If no sector numbers are specified, load all. + if snos == nil { + infos := make([]*SectorOnChainInfo, 0, sectors.Length()) + var info12 miner12.SectorOnChainInfo + if err := sectors.ForEach(&info12, func(_ int64) error { + info := fromV12SectorOnChainInfo(info12) + infos = append(infos, &info) + return nil + }); err != nil { + return nil, err + } + return infos, nil + } + + // Otherwise, load selected. + infos12, err := sectors.Load(*snos) + if err != nil { + return nil, err + } + infos := make([]*SectorOnChainInfo, len(infos12)) + for i, info12 := range infos12 { + info := fromV12SectorOnChainInfo(*info12) + infos[i] = &info + } + return infos, nil +} + +func (s *state12) loadAllocatedSectorNumbers() (bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors) + return allocatedSectors, err +} + +func (s *state12) IsAllocated(num abi.SectorNumber) (bool, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return false, err + } + + return allocatedSectors.IsSet(uint64(num)) +} + +func (s *state12) GetProvingPeriodStart() (abi.ChainEpoch, error) { + return s.State.ProvingPeriodStart, nil +} + +func (s *state12) UnallocatedSectorNumbers(count int) ([]abi.SectorNumber, error) { + allocatedSectors, err := s.loadAllocatedSectorNumbers() + if err != nil { + return nil, err + } + + allocatedRuns, err := allocatedSectors.RunIterator() + if err != nil { + return nil, err + } + + unallocatedRuns, err := rle.Subtract( + &rle.RunSliceIterator{Runs: []rle.Run{{Val: true, Len: abi.MaxSectorNumber}}}, + allocatedRuns, + ) + if err != nil { + return nil, err + } + + iter, err := rle.BitsFromRuns(unallocatedRuns) + if err != nil { + return nil, err + } + + sectors := make([]abi.SectorNumber, 0, count) + for iter.HasNext() && len(sectors) < count { + nextNo, err := iter.Next() + if err != nil { + return nil, err + } + sectors = append(sectors, abi.SectorNumber(nextNo)) + } + + return sectors, nil +} + +func (s *state12) GetAllocatedSectors() (*bitfield.BitField, error) { + var allocatedSectors bitfield.BitField + if err := s.store.Get(s.store.Context(), s.State.AllocatedSectors, &allocatedSectors); err != nil { + return nil, err + } + + return &allocatedSectors, nil +} + +func (s *state12) LoadDeadline(idx uint64) (Deadline, error) { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return nil, err + } + dl, err := dls.LoadDeadline(s.store, idx) + if err != nil { + return nil, err + } + return &deadline12{*dl, s.store}, nil +} + +func (s *state12) ForEachDeadline(cb func(uint64, Deadline) error) error { + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + return dls.ForEach(s.store, func(i uint64, dl *miner12.Deadline) error { + return cb(i, &deadline12{*dl, s.store}) + }) +} + +func (s *state12) NumDeadlines() (uint64, error) { + return miner12.WPoStPeriodDeadlines, nil +} + +func (s *state12) DeadlinesChanged(other State) (bool, error) { + other12, ok := other.(*state12) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !s.State.Deadlines.Equals(other12.Deadlines), nil +} + +func (s *state12) MinerInfoChanged(other State) (bool, error) { + other0, ok := other.(*state12) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Info.Equals(other0.State.Info), nil +} + +func (s *state12) Info() (MinerInfo, error) { + info, err := s.State.GetInfo(s.store) + if err != nil { + return MinerInfo{}, err + } + + mi := MinerInfo{ + Owner: info.Owner, + Worker: info.Worker, + ControlAddresses: info.ControlAddresses, + + PendingWorkerKey: (*WorkerKeyChange)(info.PendingWorkerKey), + + PeerId: info.PeerId, + Multiaddrs: info.Multiaddrs, + WindowPoStProofType: info.WindowPoStProofType, + SectorSize: info.SectorSize, + WindowPoStPartitionSectors: info.WindowPoStPartitionSectors, + ConsensusFaultElapsed: info.ConsensusFaultElapsed, + + Beneficiary: info.Beneficiary, + BeneficiaryTerm: BeneficiaryTerm(info.BeneficiaryTerm), + PendingBeneficiaryTerm: (*PendingBeneficiaryChange)(info.PendingBeneficiaryTerm), + } + + return mi, nil +} + +func (s *state12) DeadlineInfo(epoch abi.ChainEpoch) (*dline.Info, error) { + return s.State.RecordedDeadlineInfo(epoch), nil +} + +func (s *state12) DeadlineCronActive() (bool, error) { + return s.State.DeadlineCronActive, nil +} + +func (s *state12) sectors() (adt.Array, error) { + return adt12.AsArray(s.store, s.Sectors, miner12.SectorsAmtBitwidth) +} + +func (s *state12) decodeSectorOnChainInfo(val *cbg.Deferred) (SectorOnChainInfo, error) { + var si miner12.SectorOnChainInfo + err := si.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorOnChainInfo{}, err + } + + return fromV12SectorOnChainInfo(si), nil +} + +func (s *state12) precommits() (adt.Map, error) { + return adt12.AsMap(s.store, s.PreCommittedSectors, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) decodeSectorPreCommitOnChainInfo(val *cbg.Deferred) (SectorPreCommitOnChainInfo, error) { + var sp miner12.SectorPreCommitOnChainInfo + err := sp.UnmarshalCBOR(bytes.NewReader(val.Raw)) + if err != nil { + return SectorPreCommitOnChainInfo{}, err + } + + return fromV12SectorPreCommitOnChainInfo(sp), nil +} + +func (s *state12) EraseAllUnproven() error { + + dls, err := s.State.LoadDeadlines(s.store) + if err != nil { + return err + } + + err = dls.ForEach(s.store, func(dindx uint64, dl *miner12.Deadline) error { + ps, err := dl.PartitionsArray(s.store) + if err != nil { + return err + } + + var part miner12.Partition + err = ps.ForEach(&part, func(pindx int64) error { + _ = part.ActivateUnproven() + err = ps.Set(uint64(pindx), &part) + return nil + }) + + if err != nil { + return err + } + + dl.Partitions, err = ps.Root() + if err != nil { + return err + } + + return dls.UpdateDeadline(s.store, dindx, dl) + }) + if err != nil { + return err + } + + return s.State.SaveDeadlines(s.store, dls) + +} + +func (d *deadline12) LoadPartition(idx uint64) (Partition, error) { + p, err := d.Deadline.LoadPartition(d.store, idx) + if err != nil { + return nil, err + } + return &partition12{*p, d.store}, nil +} + +func (d *deadline12) ForEachPartition(cb func(uint64, Partition) error) error { + ps, err := d.Deadline.PartitionsArray(d.store) + if err != nil { + return err + } + var part miner12.Partition + return ps.ForEach(&part, func(i int64) error { + return cb(uint64(i), &partition12{part, d.store}) + }) +} + +func (d *deadline12) PartitionsChanged(other Deadline) (bool, error) { + other12, ok := other.(*deadline12) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + + return !d.Deadline.Partitions.Equals(other12.Deadline.Partitions), nil +} + +func (d *deadline12) PartitionsPoSted() (bitfield.BitField, error) { + return d.Deadline.PartitionsPoSted, nil +} + +func (d *deadline12) DisputableProofCount() (uint64, error) { + + ops, err := d.OptimisticProofsSnapshotArray(d.store) + if err != nil { + return 0, err + } + + return ops.Length(), nil + +} + +func (p *partition12) AllSectors() (bitfield.BitField, error) { + return p.Partition.Sectors, nil +} + +func (p *partition12) FaultySectors() (bitfield.BitField, error) { + return p.Partition.Faults, nil +} + +func (p *partition12) RecoveringSectors() (bitfield.BitField, error) { + return p.Partition.Recoveries, nil +} + +func (p *partition12) UnprovenSectors() (bitfield.BitField, error) { + return p.Partition.Unproven, nil +} + +func fromV12SectorOnChainInfo(v12 miner12.SectorOnChainInfo) SectorOnChainInfo { + info := SectorOnChainInfo{ + SectorNumber: v12.SectorNumber, + SealProof: v12.SealProof, + SealedCID: v12.SealedCID, + DealIDs: v12.DealIDs, + Activation: v12.Activation, + Expiration: v12.Expiration, + DealWeight: v12.DealWeight, + VerifiedDealWeight: v12.VerifiedDealWeight, + InitialPledge: v12.InitialPledge, + ExpectedDayReward: v12.ExpectedDayReward, + ExpectedStoragePledge: v12.ExpectedStoragePledge, + + SectorKeyCID: v12.SectorKeyCID, + } + return info +} + +func fromV12SectorPreCommitOnChainInfo(v12 miner12.SectorPreCommitOnChainInfo) SectorPreCommitOnChainInfo { + ret := SectorPreCommitOnChainInfo{ + Info: SectorPreCommitInfo{ + SealProof: v12.Info.SealProof, + SectorNumber: v12.Info.SectorNumber, + SealedCID: v12.Info.SealedCID, + SealRandEpoch: v12.Info.SealRandEpoch, + DealIDs: v12.Info.DealIDs, + Expiration: v12.Info.Expiration, + UnsealedCid: nil, + }, + PreCommitDeposit: v12.PreCommitDeposit, + PreCommitEpoch: v12.PreCommitEpoch, + } + + ret.Info.UnsealedCid = v12.Info.UnsealedCid + + return ret +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ActorKey() string { + return manifest.MinerKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/multisig/message10.go b/chain/actors/builtin/multisig/message10.go index 5f70ea3c1..8f7bb5a6f 100644 --- a/chain/actors/builtin/multisig/message10.go +++ b/chain/actors/builtin/multisig/message10.go @@ -8,7 +8,7 @@ import ( actorstypes "github.com/filecoin-project/go-state-types/actors" builtintypes "github.com/filecoin-project/go-state-types/builtin" multisig10 "github.com/filecoin-project/go-state-types/builtin/v10/multisig" - init11 "github.com/filecoin-project/go-state-types/builtin/v11/init" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" "github.com/filecoin-project/go-state-types/manifest" "github.com/filecoin-project/lotus/chain/actors" @@ -57,7 +57,7 @@ func (m message10) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init11.ExecParams{ + execParams := &init12.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/chain/actors/builtin/multisig/message11.go b/chain/actors/builtin/multisig/message11.go index a2c086614..4c7520d5d 100644 --- a/chain/actors/builtin/multisig/message11.go +++ b/chain/actors/builtin/multisig/message11.go @@ -7,8 +7,8 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" builtintypes "github.com/filecoin-project/go-state-types/builtin" - init11 "github.com/filecoin-project/go-state-types/builtin/v11/init" multisig11 "github.com/filecoin-project/go-state-types/builtin/v11/multisig" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" "github.com/filecoin-project/go-state-types/manifest" "github.com/filecoin-project/lotus/chain/actors" @@ -57,7 +57,7 @@ func (m message11) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init11.ExecParams{ + execParams := &init12.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/chain/actors/builtin/multisig/message12.go b/chain/actors/builtin/multisig/message12.go new file mode 100644 index 000000000..43658c04b --- /dev/null +++ b/chain/actors/builtin/multisig/message12.go @@ -0,0 +1,77 @@ +package multisig + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtintypes "github.com/filecoin-project/go-state-types/builtin" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + multisig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message12 struct{ message0 } + +func (m message12) Create( + signers []address.Address, threshold uint64, + unlockStart, unlockDuration abi.ChainEpoch, + initialAmount abi.TokenAmount, +) (*types.Message, error) { + + lenAddrs := uint64(len(signers)) + + if lenAddrs < threshold { + return nil, xerrors.Errorf("cannot require signing of more addresses than provided for multisig") + } + + if threshold == 0 { + threshold = lenAddrs + } + + if m.from == address.Undef { + return nil, xerrors.Errorf("must provide source address") + } + + // Set up constructor parameters for multisig + msigParams := &multisig12.ConstructorParams{ + Signers: signers, + NumApprovalsThreshold: threshold, + UnlockDuration: unlockDuration, + StartEpoch: unlockStart, + } + + enc, actErr := actors.SerializeParams(msigParams) + if actErr != nil { + return nil, actErr + } + + code, ok := actors.GetActorCodeID(actorstypes.Version12, manifest.MultisigKey) + if !ok { + return nil, xerrors.Errorf("failed to get multisig code ID") + } + + // new actors are created by invoking 'exec' on the init actor with the constructor params + execParams := &init12.ExecParams{ + CodeCID: code, + ConstructorParams: enc, + } + + enc, actErr = actors.SerializeParams(execParams) + if actErr != nil { + return nil, actErr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Method: builtintypes.MethodsInit.Exec, + Params: enc, + Value: initialAmount, + }, nil +} diff --git a/chain/actors/builtin/multisig/message8.go b/chain/actors/builtin/multisig/message8.go index 817d66726..390c94691 100644 --- a/chain/actors/builtin/multisig/message8.go +++ b/chain/actors/builtin/multisig/message8.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" builtintypes "github.com/filecoin-project/go-state-types/builtin" - init11 "github.com/filecoin-project/go-state-types/builtin/v11/init" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" multisig8 "github.com/filecoin-project/go-state-types/builtin/v8/multisig" "github.com/filecoin-project/go-state-types/manifest" @@ -57,7 +57,7 @@ func (m message8) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init11.ExecParams{ + execParams := &init12.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/chain/actors/builtin/multisig/message9.go b/chain/actors/builtin/multisig/message9.go index 1472c4e66..907bec7d5 100644 --- a/chain/actors/builtin/multisig/message9.go +++ b/chain/actors/builtin/multisig/message9.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" builtintypes "github.com/filecoin-project/go-state-types/builtin" - init11 "github.com/filecoin-project/go-state-types/builtin/v11/init" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" multisig9 "github.com/filecoin-project/go-state-types/builtin/v9/multisig" "github.com/filecoin-project/go-state-types/manifest" @@ -57,7 +57,7 @@ func (m message9) Create( } // new actors are created by invoking 'exec' on the init actor with the constructor params - execParams := &init11.ExecParams{ + execParams := &init12.ExecParams{ CodeCID: code, ConstructorParams: enc, } diff --git a/chain/actors/builtin/multisig/multisig.go b/chain/actors/builtin/multisig/multisig.go index 9ab8fffb5..71a3b7b22 100644 --- a/chain/actors/builtin/multisig/multisig.go +++ b/chain/actors/builtin/multisig/multisig.go @@ -12,7 +12,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" builtintypes "github.com/filecoin-project/go-state-types/builtin" - msig11 "github.com/filecoin-project/go-state-types/builtin/v11/multisig" + msig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -48,6 +48,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -115,6 +118,9 @@ func MakeState(store adt.Store, av actorstypes.Version, signers []address.Addres case actorstypes.Version11: return make11(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + case actorstypes.Version12: + return make12(store, signers, threshold, startEpoch, unlockDuration, initialBalance) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -141,7 +147,7 @@ type State interface { GetState() interface{} } -type Transaction = msig11.Transaction +type Transaction = msig12.Transaction var Methods = builtintypes.MethodsMultisig @@ -180,6 +186,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder { case actorstypes.Version11: return message11{message0{from}} + + case actorstypes.Version12: + return message12{message0{from}} default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } @@ -203,13 +212,13 @@ type MessageBuilder interface { } // this type is the same between v0 and v2 -type ProposalHashData = msig11.ProposalHashData -type ProposeReturn = msig11.ProposeReturn -type ProposeParams = msig11.ProposeParams -type ApproveReturn = msig11.ApproveReturn +type ProposalHashData = msig12.ProposalHashData +type ProposeReturn = msig12.ProposeReturn +type ProposeParams = msig12.ProposeParams +type ApproveReturn = msig12.ApproveReturn func txnParams(id uint64, data *ProposalHashData) ([]byte, error) { - params := msig11.TxnIDParams{ID: msig11.TxnID(id)} + params := msig12.TxnIDParams{ID: msig12.TxnID(id)} if data != nil { if data.Requester.Protocol() != address.ID { return nil, xerrors.Errorf("proposer address must be an ID address, was %s", data.Requester) @@ -244,5 +253,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/multisig/v12.go b/chain/actors/builtin/multisig/v12.go new file mode 100644 index 000000000..d3d2f3809 --- /dev/null +++ b/chain/actors/builtin/multisig/v12.go @@ -0,0 +1,138 @@ +package multisig + +import ( + "bytes" + "encoding/binary" + "fmt" + + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + msig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, signers []address.Address, threshold uint64, startEpoch abi.ChainEpoch, unlockDuration abi.ChainEpoch, initialBalance abi.TokenAmount) (State, error) { + out := state12{store: store} + out.State = msig12.State{} + out.State.Signers = signers + out.State.NumApprovalsThreshold = threshold + out.State.StartEpoch = startEpoch + out.State.UnlockDuration = unlockDuration + out.State.InitialBalance = initialBalance + + em, err := adt12.StoreEmptyMap(store, builtin12.DefaultHamtBitwidth) + if err != nil { + return nil, err + } + + out.State.PendingTxns = em + + return &out, nil +} + +type state12 struct { + msig12.State + store adt.Store +} + +func (s *state12) LockedBalance(currEpoch abi.ChainEpoch) (abi.TokenAmount, error) { + return s.State.AmountLocked(currEpoch - s.State.StartEpoch), nil +} + +func (s *state12) StartEpoch() (abi.ChainEpoch, error) { + return s.State.StartEpoch, nil +} + +func (s *state12) UnlockDuration() (abi.ChainEpoch, error) { + return s.State.UnlockDuration, nil +} + +func (s *state12) InitialBalance() (abi.TokenAmount, error) { + return s.State.InitialBalance, nil +} + +func (s *state12) Threshold() (uint64, error) { + return s.State.NumApprovalsThreshold, nil +} + +func (s *state12) Signers() ([]address.Address, error) { + return s.State.Signers, nil +} + +func (s *state12) ForEachPendingTxn(cb func(id int64, txn Transaction) error) error { + arr, err := adt12.AsMap(s.store, s.State.PendingTxns, builtin12.DefaultHamtBitwidth) + if err != nil { + return err + } + var out msig12.Transaction + return arr.ForEach(&out, func(key string) error { + txid, n := binary.Varint([]byte(key)) + if n <= 0 { + return xerrors.Errorf("invalid pending transaction key: %v", key) + } + return cb(txid, (Transaction)(out)) //nolint:unconvert + }) +} + +func (s *state12) PendingTxnChanged(other State) (bool, error) { + other12, ok := other.(*state12) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.PendingTxns.Equals(other12.PendingTxns), nil +} + +func (s *state12) transactions() (adt.Map, error) { + return adt12.AsMap(s.store, s.PendingTxns, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) decodeTransaction(val *cbg.Deferred) (Transaction, error) { + var tx msig12.Transaction + if err := tx.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Transaction{}, err + } + return Transaction(tx), nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ActorKey() string { + return manifest.MultisigKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/paych/message12.go b/chain/actors/builtin/paych/message12.go new file mode 100644 index 000000000..bd821641a --- /dev/null +++ b/chain/actors/builtin/paych/message12.go @@ -0,0 +1,109 @@ +package paych + +import ( + "golang.org/x/xerrors" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych" + paychtypes "github.com/filecoin-project/go-state-types/builtin/v8/paych" + + "github.com/filecoin-project/lotus/chain/actors" + init_ "github.com/filecoin-project/lotus/chain/actors/builtin/init" + "github.com/filecoin-project/lotus/chain/types" +) + +type message12 struct{ from address.Address } + +func (m message12) Create(to address.Address, initialAmount abi.TokenAmount) (*types.Message, error) { + + actorCodeID, ok := actors.GetActorCodeID(actorstypes.Version12, "paymentchannel") + if !ok { + return nil, xerrors.Errorf("error getting actor paymentchannel code id for actor version %d", 12) + } + + params, aerr := actors.SerializeParams(&paych12.ConstructorParams{From: m.from, To: to}) + if aerr != nil { + return nil, aerr + } + enc, aerr := actors.SerializeParams(&init12.ExecParams{ + CodeCID: actorCodeID, + ConstructorParams: params, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: init_.Address, + From: m.from, + Value: initialAmount, + Method: builtin12.MethodsInit.Exec, + Params: enc, + }, nil +} + +func (m message12) Update(paych address.Address, sv *paychtypes.SignedVoucher, secret []byte) (*types.Message, error) { + params, aerr := actors.SerializeParams(&paych12.UpdateChannelStateParams{ + + Sv: toV12SignedVoucher(*sv), + + Secret: secret, + }) + if aerr != nil { + return nil, aerr + } + + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin12.MethodsPaych.UpdateChannelState, + Params: params, + }, nil +} + +func toV12SignedVoucher(sv paychtypes.SignedVoucher) paych12.SignedVoucher { + merges := make([]paych12.Merge, len(sv.Merges)) + for i := range sv.Merges { + merges[i] = paych12.Merge{ + Lane: sv.Merges[i].Lane, + Nonce: sv.Merges[i].Nonce, + } + } + + return paych12.SignedVoucher{ + ChannelAddr: sv.ChannelAddr, + TimeLockMin: sv.TimeLockMin, + TimeLockMax: sv.TimeLockMax, + SecretHash: sv.SecretHash, + Extra: (*paych12.ModVerifyParams)(sv.Extra), + Lane: sv.Lane, + Nonce: sv.Nonce, + Amount: sv.Amount, + MinSettleHeight: sv.MinSettleHeight, + Merges: merges, + Signature: sv.Signature, + } +} + +func (m message12) Settle(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin12.MethodsPaych.Settle, + }, nil +} + +func (m message12) Collect(paych address.Address) (*types.Message, error) { + return &types.Message{ + To: paych, + From: m.from, + Value: abi.NewTokenAmount(0), + Method: builtin12.MethodsPaych.Collect, + }, nil +} diff --git a/chain/actors/builtin/paych/paych.go b/chain/actors/builtin/paych/paych.go index ccf48dbce..8a7979e95 100644 --- a/chain/actors/builtin/paych/paych.go +++ b/chain/actors/builtin/paych/paych.go @@ -50,6 +50,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -167,6 +170,9 @@ func Message(version actorstypes.Version, from address.Address) MessageBuilder { case actorstypes.Version11: return message11{from} + case actorstypes.Version12: + return message12{from} + default: panic(fmt.Sprintf("unsupported actors version: %d", version)) } @@ -208,5 +214,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/paych/v12.go b/chain/actors/builtin/paych/v12.go new file mode 100644 index 000000000..5c1330d76 --- /dev/null +++ b/chain/actors/builtin/paych/v12.go @@ -0,0 +1,135 @@ +package paych + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + "github.com/filecoin-project/go-state-types/big" + paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store) (State, error) { + out := state12{store: store} + out.State = paych12.State{} + return &out, nil +} + +type state12 struct { + paych12.State + store adt.Store + lsAmt *adt12.Array +} + +// Channel owner, who has funded the actor +func (s *state12) From() (address.Address, error) { + return s.State.From, nil +} + +// Recipient of payouts from channel +func (s *state12) To() (address.Address, error) { + return s.State.To, nil +} + +// Height at which the channel can be `Collected` +func (s *state12) SettlingAt() (abi.ChainEpoch, error) { + return s.State.SettlingAt, nil +} + +// Amount successfully redeemed through the payment channel, paid out on `Collect()` +func (s *state12) ToSend() (abi.TokenAmount, error) { + return s.State.ToSend, nil +} + +func (s *state12) getOrLoadLsAmt() (*adt12.Array, error) { + if s.lsAmt != nil { + return s.lsAmt, nil + } + + // Get the lane state from the chain + lsamt, err := adt12.AsArray(s.store, s.State.LaneStates, paych12.LaneStatesAmtBitwidth) + if err != nil { + return nil, err + } + + s.lsAmt = lsamt + return lsamt, nil +} + +// Get total number of lanes +func (s *state12) LaneCount() (uint64, error) { + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return 0, err + } + return lsamt.Length(), nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +// Iterate lane states +func (s *state12) ForEachLaneState(cb func(idx uint64, dl LaneState) error) error { + // Get the lane state from the chain + lsamt, err := s.getOrLoadLsAmt() + if err != nil { + return err + } + + // Note: we use a map instead of an array to store laneStates because the + // client sets the lane ID (the index) and potentially they could use a + // very large index. + var ls paych12.LaneState + return lsamt.ForEach(&ls, func(i int64) error { + return cb(uint64(i), &laneState12{ls}) + }) +} + +type laneState12 struct { + paych12.LaneState +} + +func (ls *laneState12) Redeemed() (big.Int, error) { + return ls.LaneState.Redeemed, nil +} + +func (ls *laneState12) Nonce() (uint64, error) { + return ls.LaneState.Nonce, nil +} + +func (s *state12) ActorKey() string { + return manifest.PaychKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/power/power.go b/chain/actors/builtin/power/power.go index f3bcef5bb..9b64ded38 100644 --- a/chain/actors/builtin/power/power.go +++ b/chain/actors/builtin/power/power.go @@ -9,7 +9,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" "github.com/filecoin-project/go-state-types/big" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -27,8 +27,8 @@ import ( ) var ( - Address = builtin11.StoragePowerActorAddr - Methods = builtin11.MethodsPower + Address = builtin12.StoragePowerActorAddr + Methods = builtin12.MethodsPower ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -51,6 +51,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -118,6 +121,9 @@ func MakeState(store adt.Store, av actorstypes.Version) (State, error) { case actorstypes.Version11: return make11(store) + case actorstypes.Version12: + return make12(store) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -183,5 +189,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/power/v12.go b/chain/actors/builtin/power/v12.go new file mode 100644 index 000000000..2e9109022 --- /dev/null +++ b/chain/actors/builtin/power/v12.go @@ -0,0 +1,207 @@ +package power + +import ( + "bytes" + "fmt" + + "github.com/ipfs/go-cid" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + power12 "github.com/filecoin-project/go-state-types/builtin/v12/power" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store) (State, error) { + out := state12{store: store} + + s, err := power12.ConstructState(store) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + power12.State + store adt.Store +} + +func (s *state12) TotalLocked() (abi.TokenAmount, error) { + return s.TotalPledgeCollateral, nil +} + +func (s *state12) TotalPower() (Claim, error) { + return Claim{ + RawBytePower: s.TotalRawBytePower, + QualityAdjPower: s.TotalQualityAdjPower, + }, nil +} + +// Committed power to the network. Includes miners below the minimum threshold. +func (s *state12) TotalCommitted() (Claim, error) { + return Claim{ + RawBytePower: s.TotalBytesCommitted, + QualityAdjPower: s.TotalQABytesCommitted, + }, nil +} + +func (s *state12) MinerPower(addr address.Address) (Claim, bool, error) { + claims, err := s.claims() + if err != nil { + return Claim{}, false, err + } + var claim power12.Claim + ok, err := claims.Get(abi.AddrKey(addr), &claim) + if err != nil { + return Claim{}, false, err + } + return Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }, ok, nil +} + +func (s *state12) MinerNominalPowerMeetsConsensusMinimum(a address.Address) (bool, error) { + return s.State.MinerNominalPowerMeetsConsensusMinimum(s.store, a) +} + +func (s *state12) TotalPowerSmoothed() (builtin.FilterEstimate, error) { + return builtin.FilterEstimate(s.State.ThisEpochQAPowerSmoothed), nil +} + +func (s *state12) MinerCounts() (uint64, uint64, error) { + return uint64(s.State.MinerAboveMinPowerCount), uint64(s.State.MinerCount), nil +} + +func (s *state12) ListAllMiners() ([]address.Address, error) { + claims, err := s.claims() + if err != nil { + return nil, err + } + + var miners []address.Address + err = claims.ForEach(nil, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + miners = append(miners, a) + return nil + }) + if err != nil { + return nil, err + } + + return miners, nil +} + +func (s *state12) ForEachClaim(cb func(miner address.Address, claim Claim) error) error { + claims, err := s.claims() + if err != nil { + return err + } + + var claim power12.Claim + return claims.ForEach(&claim, func(k string) error { + a, err := address.NewFromBytes([]byte(k)) + if err != nil { + return err + } + return cb(a, Claim{ + RawBytePower: claim.RawBytePower, + QualityAdjPower: claim.QualityAdjPower, + }) + }) +} + +func (s *state12) ClaimsChanged(other State) (bool, error) { + other12, ok := other.(*state12) + if !ok { + // treat an upgrade as a change, always + return true, nil + } + return !s.State.Claims.Equals(other12.State.Claims), nil +} + +func (s *state12) SetTotalQualityAdjPower(p abi.StoragePower) error { + s.State.TotalQualityAdjPower = p + return nil +} + +func (s *state12) SetTotalRawBytePower(p abi.StoragePower) error { + s.State.TotalRawBytePower = p + return nil +} + +func (s *state12) SetThisEpochQualityAdjPower(p abi.StoragePower) error { + s.State.ThisEpochQualityAdjPower = p + return nil +} + +func (s *state12) SetThisEpochRawBytePower(p abi.StoragePower) error { + s.State.ThisEpochRawBytePower = p + return nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) claims() (adt.Map, error) { + return adt12.AsMap(s.store, s.Claims, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) decodeClaim(val *cbg.Deferred) (Claim, error) { + var ci power12.Claim + if err := ci.UnmarshalCBOR(bytes.NewReader(val.Raw)); err != nil { + return Claim{}, err + } + return fromV12Claim(ci), nil +} + +func fromV12Claim(v12 power12.Claim) Claim { + return Claim{ + RawBytePower: v12.RawBytePower, + QualityAdjPower: v12.QualityAdjPower, + } +} + +func (s *state12) ActorKey() string { + return manifest.PowerKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/registry.go b/chain/actors/builtin/registry.go index 4addbd451..6ba5fef03 100644 --- a/chain/actors/builtin/registry.go +++ b/chain/actors/builtin/registry.go @@ -42,6 +42,22 @@ import ( reward11 "github.com/filecoin-project/go-state-types/builtin/v11/reward" system11 "github.com/filecoin-project/go-state-types/builtin/v11/system" verifreg11 "github.com/filecoin-project/go-state-types/builtin/v11/verifreg" + account12 "github.com/filecoin-project/go-state-types/builtin/v12/account" + cron12 "github.com/filecoin-project/go-state-types/builtin/v12/cron" + datacap12 "github.com/filecoin-project/go-state-types/builtin/v12/datacap" + eam12 "github.com/filecoin-project/go-state-types/builtin/v12/eam" + ethaccount12 "github.com/filecoin-project/go-state-types/builtin/v12/ethaccount" + evm12 "github.com/filecoin-project/go-state-types/builtin/v12/evm" + _init12 "github.com/filecoin-project/go-state-types/builtin/v12/init" + market12 "github.com/filecoin-project/go-state-types/builtin/v12/market" + miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner" + multisig12 "github.com/filecoin-project/go-state-types/builtin/v12/multisig" + paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych" + placeholder12 "github.com/filecoin-project/go-state-types/builtin/v12/placeholder" + power12 "github.com/filecoin-project/go-state-types/builtin/v12/power" + reward12 "github.com/filecoin-project/go-state-types/builtin/v12/reward" + system12 "github.com/filecoin-project/go-state-types/builtin/v12/system" + verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg" account8 "github.com/filecoin-project/go-state-types/builtin/v8/account" cron8 "github.com/filecoin-project/go-state-types/builtin/v8/cron" _init8 "github.com/filecoin-project/go-state-types/builtin/v8/init" @@ -497,6 +513,110 @@ func MakeRegistry(av actorstypes.Version) []RegistryEntry { } } + case actorstypes.Version12: + for key, codeID := range codeIDs { + switch key { + case manifest.AccountKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: account12.Methods, + state: new(account12.State), + }) + case manifest.CronKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: cron12.Methods, + state: new(cron12.State), + }) + case manifest.InitKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: _init12.Methods, + state: new(_init12.State), + }) + case manifest.MarketKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: market12.Methods, + state: new(market12.State), + }) + case manifest.MinerKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: miner12.Methods, + state: new(miner12.State), + }) + case manifest.MultisigKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: multisig12.Methods, + state: new(multisig12.State), + }) + case manifest.PaychKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: paych12.Methods, + state: new(paych12.State), + }) + case manifest.PowerKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: power12.Methods, + state: new(power12.State), + }) + case manifest.RewardKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: reward12.Methods, + state: new(reward12.State), + }) + case manifest.SystemKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: system12.Methods, + state: new(system12.State), + }) + case manifest.VerifregKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: verifreg12.Methods, + state: new(verifreg12.State), + }) + case manifest.DatacapKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: datacap12.Methods, + state: new(datacap12.State), + }) + + case manifest.EvmKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: evm12.Methods, + state: new(evm12.State), + }) + case manifest.EamKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: eam12.Methods, + state: nil, + }) + case manifest.PlaceholderKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: placeholder12.Methods, + state: nil, + }) + case manifest.EthAccountKey: + registry = append(registry, RegistryEntry{ + code: codeID, + methods: ethaccount12.Methods, + state: nil, + }) + + } + } + default: panic("expected version v8 and up only, use specs-actors for v0-7") } diff --git a/chain/actors/builtin/reward/reward.go b/chain/actors/builtin/reward/reward.go index b0060a217..3c6463645 100644 --- a/chain/actors/builtin/reward/reward.go +++ b/chain/actors/builtin/reward/reward.go @@ -6,7 +6,7 @@ import ( "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" @@ -25,8 +25,8 @@ import ( ) var ( - Address = builtin11.RewardActorAddr - Methods = builtin11.MethodsReward + Address = builtin12.RewardActorAddr + Methods = builtin12.MethodsReward ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, currRealizedPower abi.St case actorstypes.Version11: return make11(store, currRealizedPower) + case actorstypes.Version12: + return make12(store, currRealizedPower) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -159,5 +165,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/reward/v12.go b/chain/actors/builtin/reward/v12.go new file mode 100644 index 000000000..ecc8ff5a0 --- /dev/null +++ b/chain/actors/builtin/reward/v12.go @@ -0,0 +1,120 @@ +package reward + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + "github.com/filecoin-project/go-state-types/abi" + actorstypes "github.com/filecoin-project/go-state-types/actors" + miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner" + reward12 "github.com/filecoin-project/go-state-types/builtin/v12/reward" + smoothing12 "github.com/filecoin-project/go-state-types/builtin/v12/util/smoothing" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" + "github.com/filecoin-project/lotus/chain/actors/builtin" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, currRealizedPower abi.StoragePower) (State, error) { + out := state12{store: store} + out.State = *reward12.ConstructState(currRealizedPower) + return &out, nil +} + +type state12 struct { + reward12.State + store adt.Store +} + +func (s *state12) ThisEpochReward() (abi.TokenAmount, error) { + return s.State.ThisEpochReward, nil +} + +func (s *state12) ThisEpochRewardSmoothed() (builtin.FilterEstimate, error) { + + return builtin.FilterEstimate{ + PositionEstimate: s.State.ThisEpochRewardSmoothed.PositionEstimate, + VelocityEstimate: s.State.ThisEpochRewardSmoothed.VelocityEstimate, + }, nil + +} + +func (s *state12) ThisEpochBaselinePower() (abi.StoragePower, error) { + return s.State.ThisEpochBaselinePower, nil +} + +func (s *state12) TotalStoragePowerReward() (abi.TokenAmount, error) { + return s.State.TotalStoragePowerReward, nil +} + +func (s *state12) EffectiveBaselinePower() (abi.StoragePower, error) { + return s.State.EffectiveBaselinePower, nil +} + +func (s *state12) EffectiveNetworkTime() (abi.ChainEpoch, error) { + return s.State.EffectiveNetworkTime, nil +} + +func (s *state12) CumsumBaseline() (reward12.Spacetime, error) { + return s.State.CumsumBaseline, nil +} + +func (s *state12) CumsumRealized() (reward12.Spacetime, error) { + return s.State.CumsumRealized, nil +} + +func (s *state12) InitialPledgeForPower(qaPower abi.StoragePower, networkTotalPledge abi.TokenAmount, networkQAPower *builtin.FilterEstimate, circSupply abi.TokenAmount) (abi.TokenAmount, error) { + return miner12.InitialPledgeForPower( + qaPower, + s.State.ThisEpochBaselinePower, + s.State.ThisEpochRewardSmoothed, + smoothing12.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + circSupply, + ), nil +} + +func (s *state12) PreCommitDepositForPower(networkQAPower builtin.FilterEstimate, sectorWeight abi.StoragePower) (abi.TokenAmount, error) { + return miner12.PreCommitDepositForPower(s.State.ThisEpochRewardSmoothed, + smoothing12.FilterEstimate{ + PositionEstimate: networkQAPower.PositionEstimate, + VelocityEstimate: networkQAPower.VelocityEstimate, + }, + sectorWeight), nil +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) ActorKey() string { + return manifest.RewardKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/system/system.go b/chain/actors/builtin/system/system.go index 4db8db610..2a2b703bb 100644 --- a/chain/actors/builtin/system/system.go +++ b/chain/actors/builtin/system/system.go @@ -5,7 +5,7 @@ import ( "golang.org/x/xerrors" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/manifest" builtin0 "github.com/filecoin-project/specs-actors/actors/builtin" builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" @@ -21,7 +21,7 @@ import ( ) var ( - Address = builtin11.SystemActorAddr + Address = builtin12.SystemActorAddr ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -44,6 +44,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -111,6 +114,9 @@ func MakeState(store adt.Store, av actorstypes.Version, builtinActors cid.Cid) ( case actorstypes.Version11: return make11(store, builtinActors) + case actorstypes.Version12: + return make12(store, builtinActors) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -138,5 +144,6 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/builtin/system/v12.go b/chain/actors/builtin/system/v12.go new file mode 100644 index 000000000..71938e799 --- /dev/null +++ b/chain/actors/builtin/system/v12.go @@ -0,0 +1,72 @@ +package system + +import ( + "fmt" + + "github.com/ipfs/go-cid" + + actorstypes "github.com/filecoin-project/go-state-types/actors" + system12 "github.com/filecoin-project/go-state-types/builtin/v12/system" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, builtinActors cid.Cid) (State, error) { + out := state12{store: store} + out.State = system12.State{ + BuiltinActors: builtinActors, + } + return &out, nil +} + +type state12 struct { + system12.State + store adt.Store +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) GetBuiltinActors() cid.Cid { + + return s.State.BuiltinActors + +} + +func (s *state12) SetBuiltinActors(c cid.Cid) error { + + s.State.BuiltinActors = c + return nil + +} + +func (s *state12) ActorKey() string { + return manifest.SystemKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/v12.go b/chain/actors/builtin/verifreg/v12.go new file mode 100644 index 000000000..98b5c9add --- /dev/null +++ b/chain/actors/builtin/verifreg/v12.go @@ -0,0 +1,152 @@ +package verifreg + +import ( + "fmt" + + "github.com/ipfs/go-cid" + "golang.org/x/xerrors" + + "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/big" + builtin12 "github.com/filecoin-project/go-state-types/builtin" + adt12 "github.com/filecoin-project/go-state-types/builtin/v12/util/adt" + verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg" + verifreg9 "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" + "github.com/filecoin-project/go-state-types/manifest" + + "github.com/filecoin-project/lotus/chain/actors" + "github.com/filecoin-project/lotus/chain/actors/adt" +) + +var _ State = (*state12)(nil) + +func load12(store adt.Store, root cid.Cid) (State, error) { + out := state12{store: store} + err := store.Get(store.Context(), root, &out) + if err != nil { + return nil, err + } + return &out, nil +} + +func make12(store adt.Store, rootKeyAddress address.Address) (State, error) { + out := state12{store: store} + + s, err := verifreg12.ConstructState(store, rootKeyAddress) + if err != nil { + return nil, err + } + + out.State = *s + + return &out, nil +} + +type state12 struct { + verifreg12.State + store adt.Store +} + +func (s *state12) RootKey() (address.Address, error) { + return s.State.RootKey, nil +} + +func (s *state12) VerifiedClientDataCap(addr address.Address) (bool, abi.StoragePower, error) { + + return false, big.Zero(), xerrors.Errorf("unsupported in actors v12") + +} + +func (s *state12) VerifierDataCap(addr address.Address) (bool, abi.StoragePower, error) { + return getDataCap(s.store, actors.Version12, s.verifiers, addr) +} + +func (s *state12) RemoveDataCapProposalID(verifier address.Address, client address.Address) (bool, uint64, error) { + return getRemoveDataCapProposalID(s.store, actors.Version12, s.removeDataCapProposalIDs, verifier, client) +} + +func (s *state12) ForEachVerifier(cb func(addr address.Address, dcap abi.StoragePower) error) error { + return forEachCap(s.store, actors.Version12, s.verifiers, cb) +} + +func (s *state12) ForEachClient(cb func(addr address.Address, dcap abi.StoragePower) error) error { + + return xerrors.Errorf("unsupported in actors v12") + +} + +func (s *state12) verifiedClients() (adt.Map, error) { + + return nil, xerrors.Errorf("unsupported in actors v12") + +} + +func (s *state12) verifiers() (adt.Map, error) { + return adt12.AsMap(s.store, s.Verifiers, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) removeDataCapProposalIDs() (adt.Map, error) { + return adt12.AsMap(s.store, s.RemoveDataCapProposalIDs, builtin12.DefaultHamtBitwidth) +} + +func (s *state12) GetState() interface{} { + return &s.State +} + +func (s *state12) GetAllocation(clientIdAddr address.Address, allocationId verifreg9.AllocationId) (*Allocation, bool, error) { + + alloc, ok, err := s.FindAllocation(s.store, clientIdAddr, verifreg12.AllocationId(allocationId)) + return (*Allocation)(alloc), ok, err +} + +func (s *state12) GetAllocations(clientIdAddr address.Address) (map[AllocationId]Allocation, error) { + + v12Map, err := s.LoadAllocationsToMap(s.store, clientIdAddr) + + retMap := make(map[AllocationId]Allocation, len(v12Map)) + for k, v := range v12Map { + retMap[AllocationId(k)] = Allocation(v) + } + + return retMap, err + +} + +func (s *state12) GetClaim(providerIdAddr address.Address, claimId verifreg9.ClaimId) (*Claim, bool, error) { + + claim, ok, err := s.FindClaim(s.store, providerIdAddr, verifreg12.ClaimId(claimId)) + return (*Claim)(claim), ok, err + +} + +func (s *state12) GetClaims(providerIdAddr address.Address) (map[ClaimId]Claim, error) { + + v12Map, err := s.LoadClaimsToMap(s.store, providerIdAddr) + + retMap := make(map[ClaimId]Claim, len(v12Map)) + for k, v := range v12Map { + retMap[ClaimId(k)] = Claim(v) + } + + return retMap, err + +} + +func (s *state12) ActorKey() string { + return manifest.VerifregKey +} + +func (s *state12) ActorVersion() actorstypes.Version { + return actorstypes.Version12 +} + +func (s *state12) Code() cid.Cid { + code, ok := actors.GetActorCodeID(s.ActorVersion(), s.ActorKey()) + if !ok { + panic(fmt.Errorf("didn't find actor %v code id for actor version %d", s.ActorKey(), s.ActorVersion())) + } + + return code +} diff --git a/chain/actors/builtin/verifreg/verifreg.go b/chain/actors/builtin/verifreg/verifreg.go index 678a776bd..c5ece39da 100644 --- a/chain/actors/builtin/verifreg/verifreg.go +++ b/chain/actors/builtin/verifreg/verifreg.go @@ -7,7 +7,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" actorstypes "github.com/filecoin-project/go-state-types/actors" - builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" verifregtypes "github.com/filecoin-project/go-state-types/builtin/v9/verifreg" "github.com/filecoin-project/go-state-types/cbor" "github.com/filecoin-project/go-state-types/manifest" @@ -25,8 +25,8 @@ import ( ) var ( - Address = builtin11.VerifiedRegistryActorAddr - Methods = builtin11.MethodsVerifiedRegistry + Address = builtin12.VerifiedRegistryActorAddr + Methods = builtin12.MethodsVerifiedRegistry ) func Load(store adt.Store, act *types.Actor) (State, error) { @@ -49,6 +49,9 @@ func Load(store adt.Store, act *types.Actor) (State, error) { case actorstypes.Version11: return load11(store, act.Head) + case actorstypes.Version12: + return load12(store, act.Head) + } } @@ -116,6 +119,9 @@ func MakeState(store adt.Store, av actorstypes.Version, rootKeyAddress address.A case actorstypes.Version11: return make11(store, rootKeyAddress) + case actorstypes.Version12: + return make12(store, rootKeyAddress) + } return nil, xerrors.Errorf("unknown actor version %d", av) } @@ -153,6 +159,7 @@ func AllCodes() []cid.Cid { (&state9{}).Code(), (&state10{}).Code(), (&state11{}).Code(), + (&state12{}).Code(), } } diff --git a/chain/actors/policy/policy.go b/chain/actors/policy/policy.go index 4b90c46a0..e4c50246f 100644 --- a/chain/actors/policy/policy.go +++ b/chain/actors/policy/policy.go @@ -8,6 +8,7 @@ import ( "github.com/filecoin-project/go-state-types/big" builtin10 "github.com/filecoin-project/go-state-types/builtin" builtin11 "github.com/filecoin-project/go-state-types/builtin" + builtin12 "github.com/filecoin-project/go-state-types/builtin" builtin8 "github.com/filecoin-project/go-state-types/builtin" builtin9 "github.com/filecoin-project/go-state-types/builtin" market10 "github.com/filecoin-project/go-state-types/builtin/v10/market" @@ -15,8 +16,11 @@ import ( verifreg10 "github.com/filecoin-project/go-state-types/builtin/v10/verifreg" market11 "github.com/filecoin-project/go-state-types/builtin/v11/market" miner11 "github.com/filecoin-project/go-state-types/builtin/v11/miner" - paych11 "github.com/filecoin-project/go-state-types/builtin/v11/paych" verifreg11 "github.com/filecoin-project/go-state-types/builtin/v11/verifreg" + market12 "github.com/filecoin-project/go-state-types/builtin/v12/market" + miner12 "github.com/filecoin-project/go-state-types/builtin/v12/miner" + paych12 "github.com/filecoin-project/go-state-types/builtin/v12/paych" + verifreg12 "github.com/filecoin-project/go-state-types/builtin/v12/verifreg" market8 "github.com/filecoin-project/go-state-types/builtin/v8/market" miner8 "github.com/filecoin-project/go-state-types/builtin/v8/miner" verifreg8 "github.com/filecoin-project/go-state-types/builtin/v8/verifreg" @@ -55,10 +59,10 @@ import ( ) const ( - ChainFinality = miner11.ChainFinality + ChainFinality = miner12.ChainFinality SealRandomnessLookback = ChainFinality - PaychSettleDelay = paych11.SettleDelay - MaxPreCommitRandomnessLookback = builtin11.EpochsInDay + SealRandomnessLookback + PaychSettleDelay = paych12.SettleDelay + MaxPreCommitRandomnessLookback = builtin12.EpochsInDay + SealRandomnessLookback ) // SetSupportedProofTypes sets supported proof types, across all actor versions. @@ -171,11 +175,13 @@ func SetPreCommitChallengeDelay(delay abi.ChainEpoch) { miner11.PreCommitChallengeDelay = delay + miner12.PreCommitChallengeDelay = delay + } // TODO: this function shouldn't really exist. Instead, the API should expose the precommit delay. func GetPreCommitChallengeDelay() abi.ChainEpoch { - return miner11.PreCommitChallengeDelay + return miner12.PreCommitChallengeDelay } // SetConsensusMinerMinPower sets the minimum power of an individual miner must @@ -225,6 +231,10 @@ func SetConsensusMinerMinPower(p abi.StoragePower) { policy.ConsensusMinerMinPower = p } + for _, policy := range builtin12.PoStProofPolicies { + policy.ConsensusMinerMinPower = p + } + } // SetMinVerifiedDealSize sets the minimum size of a verified deal. This should @@ -253,6 +263,8 @@ func SetMinVerifiedDealSize(size abi.StoragePower) { verifreg11.MinVerifiedDealSize = size + verifreg12.MinVerifiedDealSize = size + } func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProof) (abi.ChainEpoch, error) { @@ -302,6 +314,10 @@ func GetMaxProveCommitDuration(ver actorstypes.Version, t abi.RegisteredSealProo return miner11.MaxProveCommitDuration[t], nil + case actorstypes.Version12: + + return miner12.MaxProveCommitDuration[t], nil + default: return 0, xerrors.Errorf("unsupported actors version") } @@ -362,6 +378,11 @@ func SetProviderCollateralSupplyTarget(num, denom big.Int) { Denominator: denom, } + market12.ProviderCollateralSupplyTarget = builtin12.BigFrac{ + Numerator: num, + Denominator: denom, + } + } func DealProviderCollateralBounds( @@ -430,13 +451,18 @@ func DealProviderCollateralBounds( min, max := market11.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) return min, max, nil + case actorstypes.Version12: + + min, max := market12.DealProviderCollateralBounds(size, verified, rawBytePower, qaPower, baselinePower, circulatingFil) + return min, max, nil + default: return big.Zero(), big.Zero(), xerrors.Errorf("unsupported actors version") } } func DealDurationBounds(pieceSize abi.PaddedPieceSize) (min, max abi.ChainEpoch) { - return market11.DealDurationBounds(pieceSize) + return market12.DealDurationBounds(pieceSize) } // Sets the challenge window and scales the proving period to match (such that @@ -512,6 +538,13 @@ func SetWPoStChallengeWindow(period abi.ChainEpoch) { // scale it if we're scaling the challenge period. miner11.WPoStDisputeWindow = period * 30 + miner12.WPoStChallengeWindow = period + miner12.WPoStProvingPeriod = period * abi.ChainEpoch(miner12.WPoStPeriodDeadlines) + + // by default, this is 2x finality which is 30 periods. + // scale it if we're scaling the challenge period. + miner12.WPoStDisputeWindow = period * 30 + } func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { @@ -524,15 +557,15 @@ func GetWinningPoStSectorSetLookback(nwVer network.Version) abi.ChainEpoch { } func GetMaxSectorExpirationExtension() abi.ChainEpoch { - return miner11.MaxSectorExpirationExtension + return miner12.MaxSectorExpirationExtension } func GetMinSectorExpiration() abi.ChainEpoch { - return miner11.MinSectorExpiration + return miner12.MinSectorExpiration } func GetMaxPoStPartitions(nv network.Version, p abi.RegisteredPoStProof) (int, error) { - sectorsPerPart, err := builtin11.PoStProofWindowPoStPartitionSectors(p) + sectorsPerPart, err := builtin12.PoStProofWindowPoStPartitionSectors(p) if err != nil { return 0, err } @@ -552,7 +585,7 @@ func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime } - return builtin11.SealProofPoliciesV11[proof].SectorMaxLifetime + return builtin12.SealProofPoliciesV11[proof].SectorMaxLifetime } func GetAddressedSectorsMax(nwVer network.Version) (int, error) { @@ -595,6 +628,9 @@ func GetAddressedSectorsMax(nwVer network.Version) (int, error) { case actorstypes.Version11: return miner11.AddressedSectorsMax, nil + case actorstypes.Version12: + return miner12.AddressedSectorsMax, nil + default: return 0, xerrors.Errorf("unsupported network version") } @@ -652,6 +688,10 @@ func GetDeclarationsMax(nwVer network.Version) (int, error) { return miner11.DeclarationsMax, nil + case actorstypes.Version12: + + return miner12.DeclarationsMax, nil + default: return 0, xerrors.Errorf("unsupported network version") } @@ -708,6 +748,10 @@ func AggregateProveCommitNetworkFee(nwVer network.Version, aggregateSize int, ba return miner11.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + case actorstypes.Version12: + + return miner12.AggregateProveCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), xerrors.Errorf("unsupported network version") } @@ -764,6 +808,10 @@ func AggregatePreCommitNetworkFee(nwVer network.Version, aggregateSize int, base return miner11.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + case actorstypes.Version12: + + return miner12.AggregatePreCommitNetworkFee(aggregateSize, baseFee), nil + default: return big.Zero(), xerrors.Errorf("unsupported network version") } diff --git a/chain/actors/version.go b/chain/actors/version.go index 3a5b935bf..92c0da006 100644 --- a/chain/actors/version.go +++ b/chain/actors/version.go @@ -14,9 +14,9 @@ const ({{range .actorVersions}} /* inline-gen start */ -var LatestVersion = 11 +var LatestVersion = 12 -var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} +var Versions = []int{0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12} const ( Version0 Version = 0 @@ -30,6 +30,7 @@ const ( Version9 Version = 9 Version10 Version = 10 Version11 Version = 11 + Version12 Version = 12 ) /* inline-gen end */ diff --git a/chain/consensus/filcns/compute_state.go b/chain/consensus/filcns/compute_state.go index ea3902d20..5bafb981d 100644 --- a/chain/consensus/filcns/compute_state.go +++ b/chain/consensus/filcns/compute_state.go @@ -50,8 +50,11 @@ func NewActorRegistry() *vm.ActorRegistry { inv.Register(actorstypes.Version7, vm.ActorsVersionPredicate(actorstypes.Version7), builtin.MakeRegistryLegacy(exported7.BuiltinActors())) inv.Register(actorstypes.Version8, vm.ActorsVersionPredicate(actorstypes.Version8), builtin.MakeRegistry(actorstypes.Version8)) inv.Register(actorstypes.Version9, vm.ActorsVersionPredicate(actorstypes.Version9), builtin.MakeRegistry(actorstypes.Version9)) + + // Hyperspace started with actors v10. inv.Register(actorstypes.Version10, vm.ActorsVersionPredicate(actorstypes.Version10), builtin.MakeRegistry(actorstypes.Version10)) inv.Register(actorstypes.Version11, vm.ActorsVersionPredicate(actorstypes.Version11), builtin.MakeRegistry(actorstypes.Version11)) + inv.Register(actorstypes.Version12, vm.ActorsVersionPredicate(actorstypes.Version12), builtin.MakeRegistry(actorstypes.Version12)) return inv } @@ -192,7 +195,7 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, var ( receipts []*types.MessageReceipt storingEvents = sm.ChainStore().IsStoringEvents() - events [][]types.Event + events [][]cbg.CBORMarshaler processedMsgs = make(map[cid.Cid]struct{}) ) @@ -284,12 +287,15 @@ func (t *TipSetExecutor) ApplyBlocks(ctx context.Context, return cid.Undef, cid.Undef, xerrors.Errorf("failed to build receipts amt: %w", err) } + cst := cbor.NewCborStore(sm.ChainStore().ChainBlockstore()) + // Slice will be empty if not storing events. for i, evs := range events { if len(evs) == 0 { continue } - switch root, err := t.StoreEventsAMT(ctx, sm.ChainStore(), evs); { + + switch root, err := amt4.FromArray(ctx, cst, evs, amt4.UseTreeBitWidth(types.EventAMTBitwidth)); { case err != nil: return cid.Undef, cid.Undef, xerrors.Errorf("failed to store events amt: %w", err) case i >= len(receipts): @@ -359,13 +365,4 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, return t.ApplyBlocks(ctx, sm, parentEpoch, pstate, fbmsgs, blks[0].Height, r, em, vmTracing, baseFee, ts) } -func (t *TipSetExecutor) StoreEventsAMT(ctx context.Context, cs *store.ChainStore, events []types.Event) (cid.Cid, error) { - cst := cbor.NewCborStore(cs.ChainBlockstore()) - objs := make([]cbg.CBORMarshaler, len(events)) - for i := 0; i < len(events); i++ { - objs[i] = &events[i] - } - return amt4.FromArray(ctx, cst, objs, amt4.UseTreeBitWidth(types.EventAMTBitwidth)) -} - var _ stmgr.Executor = &TipSetExecutor{} diff --git a/chain/consensus/filcns/filecoin.go b/chain/consensus/filcns/filecoin.go index 2cd680746..7f94e4806 100644 --- a/chain/consensus/filcns/filecoin.go +++ b/chain/consensus/filcns/filecoin.go @@ -592,7 +592,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl return xerrors.Errorf("failed to resolve key addr: %w", err) } - if err := chain.AuthenticateMessage(m, kaddr); err != nil { + if err := chain.AuthenticateMessage(m, kaddr, nv); err != nil { return xerrors.Errorf("failed to validate signature: %w", err) } diff --git a/chain/consensus/filcns/upgrades.go b/chain/consensus/filcns/upgrades.go index b82ce6fff..a8ce5c9c6 100644 --- a/chain/consensus/filcns/upgrades.go +++ b/chain/consensus/filcns/upgrades.go @@ -249,6 +249,10 @@ func DefaultUpgradeSchedule() stmgr.UpgradeSchedule { Height: build.UpgradeHyperspaceNV19Height, Network: network.Version19, Migration: UpgradeActorsV11, + }, { + Height: build.UpgradeHyperspaceNV20Height, + Network: network.Version20, + Migration: UpgradeActorsV12, }, } @@ -1705,7 +1709,6 @@ func upgradeActorsV10Common( func UpgradeActorsV11(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, _ stmgr.ExecMonitor, root cid.Cid, _ abi.ChainEpoch, _ *types.TipSet) (cid.Cid, error) { oldAv := actorstypes.Version10 newAv := actorstypes.Version11 - // This may change for upgrade oldStateTreeVersion := types.StateTreeVersion5 newStateTreeVersion := types.StateTreeVersion5 @@ -1723,6 +1726,26 @@ func UpgradeActorsV11(ctx context.Context, sm *stmgr.StateManager, _ stmgr.Migra return LiteMigration(ctx, bstore, newActorsManifestCid, root, oldAv, newAv, oldStateTreeVersion, newStateTreeVersion) } +func UpgradeActorsV12(ctx context.Context, sm *stmgr.StateManager, _ stmgr.MigrationCache, _ stmgr.ExecMonitor, root cid.Cid, _ abi.ChainEpoch, _ *types.TipSet) (cid.Cid, error) { + oldAv := actorstypes.Version11 + newAv := actorstypes.Version12 + oldStateTreeVersion := types.StateTreeVersion5 + newStateTreeVersion := types.StateTreeVersion5 + + // ensure that the manifest is loaded in the blockstore + if err := bundle.LoadBundles(ctx, sm.ChainStore().StateBlockstore(), newAv); err != nil { + return cid.Undef, xerrors.Errorf("failed to load manifest bundle: %w", err) + } + + newActorsManifestCid, ok := actors.GetManifest(newAv) + if !ok { + return cid.Undef, xerrors.Errorf("no manifest CID for actors v12 upgrade") + } + + bstore := sm.ChainStore().StateBlockstore() + return LiteMigration(ctx, bstore, newActorsManifestCid, root, oldAv, newAv, oldStateTreeVersion, newStateTreeVersion) +} + func LiteMigration(ctx context.Context, bstore blockstore.Blockstore, newActorsManifestCid cid.Cid, root cid.Cid, oldAv actorstypes.Version, newAv actorstypes.Version, oldStateTreeVersion types.StateTreeVersion, newStateTreeVersion types.StateTreeVersion) (cid.Cid, error) { buf := blockstore.NewTieredBstore(bstore, blockstore.NewMemorySync()) store := store.ActorStore(ctx, buf) diff --git a/chain/events/filter/event.go b/chain/events/filter/event.go index b821a2f83..a823855a0 100644 --- a/chain/events/filter/event.go +++ b/chain/events/filter/event.go @@ -3,16 +3,13 @@ package filter import ( "bytes" "context" - "math" "sync" "time" "github.com/ipfs/go-cid" - cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - amt4 "github.com/filecoin-project/go-amt-ipld/v4" "github.com/filecoin-project/go-state-types/abi" blockadt "github.com/filecoin-project/specs-actors/actors/util/adt" @@ -291,6 +288,7 @@ func (e *executedMessage) Events() []*types.Event { type EventFilterManager struct { ChainStore *cstore.ChainStore + EventGetter func(context.Context, cid.Cid) ([]types.Event, error) AddressResolver func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) MaxFilterResults int EventIndex *EventIndex @@ -449,30 +447,15 @@ func (m *EventFilterManager) loadExecutedMessages(ctx context.Context, msgTs, rc continue } - evtArr, err := amt4.LoadAMT(ctx, st, *rct.EventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth)) + evs, err := m.EventGetter(ctx, *rct.EventsRoot) if err != nil { - return nil, xerrors.Errorf("load events amt: %w", err) + return nil, xerrors.Errorf("failed to get events: %w", err) } - - ems[i].evs = make([]*types.Event, evtArr.Len()) - var evt types.Event - err = evtArr.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error { - if u > math.MaxInt { - return xerrors.Errorf("too many events") - } - if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil { - return err - } - - cpy := evt - ems[i].evs[int(u)] = &cpy //nolint:scopelint - return nil - }) - - if err != nil { - return nil, xerrors.Errorf("read events: %w", err) + ems[i].evs = make([]*types.Event, 0, len(evs)) + for _, ev := range evs { + ev := ev + ems[i].evs = append(ems[i].evs, &ev) } - } return ems, nil diff --git a/chain/events/filter/index.go b/chain/events/filter/index.go index ab4e24493..6962fcaa3 100644 --- a/chain/events/filter/index.go +++ b/chain/events/filter/index.go @@ -1,15 +1,20 @@ package filter import ( + "bytes" "context" "database/sql" + "encoding/hex" "errors" "fmt" "sort" + "strconv" "strings" "github.com/ipfs/go-cid" + logging "github.com/ipfs/go-log/v2" _ "github.com/mattn/go-sqlite3" + cbg "github.com/whyrusleeping/cbor-gen" "golang.org/x/xerrors" "github.com/filecoin-project/go-address" @@ -56,11 +61,11 @@ var ddls = []string{ version UINT64 NOT NULL UNIQUE )`, - // version 1. - `INSERT OR IGNORE INTO _meta (version) VALUES (1)`, + // set the version + `INSERT OR IGNORE INTO _meta (version) VALUES (` + strconv.Itoa(schemaVersion) + `)`, } -const schemaVersion = 1 +const schemaVersion = 2 const ( insertEvent = `INSERT OR IGNORE INTO event @@ -72,6 +77,8 @@ const ( VALUES(?, ?, ?, ?, ?, ?)` ) +var log = logging.Logger("event_index") + type EventIndex struct { db *sql.DB } @@ -89,6 +96,7 @@ func NewEventIndex(path string) (*EventIndex, error) { } } + var version int q, err := db.Query("SELECT name FROM sqlite_master WHERE type='table' AND name='_meta';") if err == sql.ErrNoRows || !q.Next() { // empty database, create the schema @@ -101,25 +109,25 @@ func NewEventIndex(path string) (*EventIndex, error) { } else if err != nil { _ = db.Close() return nil, xerrors.Errorf("looking for _meta table: %w", err) - } else { - // Ensure we don't open a database from a different schema version + } - row := db.QueryRow("SELECT max(version) FROM _meta") - var version int - err := row.Scan(&version) - if err != nil { - _ = db.Close() - return nil, xerrors.Errorf("invalid database version: no version found") - } - if version != schemaVersion { - _ = db.Close() - return nil, xerrors.Errorf("invalid database version: got %d, expected %d", version, schemaVersion) + row := db.QueryRow("SELECT max(version) FROM _meta") + if err := row.Scan(&version); err != nil { + _ = db.Close() + return nil, xerrors.Errorf("invalid database version: no version found") + } + + // Create the event index. + idx := &EventIndex{db: db} + + // Run any necessary migrations. + if version != schemaVersion { + if err := idx.RunMigration(version, schemaVersion); err != nil { + return nil, xerrors.Errorf("failed to run event index migration from v%d to v%d: %w", version, schemaVersion, err) } } - return &EventIndex{ - db: db, - }, nil + return idx, nil } func (ei *EventIndex) Close() error { @@ -404,3 +412,118 @@ func (ei *EventIndex) PrefillFilter(ctx context.Context, f *EventFilter) error { return nil } + +func (ei *EventIndex) RunMigration(from, to int) error { + if from != 1 && to != 2 { + return nil + } + + tx, err := ei.db.Begin() + if err != nil { + return err + } + defer tx.Rollback() //nolint + + if _, err = tx.Exec(`ALTER TABLE event_entry ADD COLUMN codec INTEGER`); err != nil { + return xerrors.Errorf("failed to alter table event_entry to add codec column: %w", err) + } + + log.Warnw("[migration v1=>v2] event_entry table schema updated") + + res, err := tx.Exec(`UPDATE event_entry SET codec = ? WHERE codec IS NULL`, 0x55) + if err != nil { + return xerrors.Errorf("failed to update table event_entry to set codec 0x55: %w", err) + } + n, _ := res.RowsAffected() + log.Warnw("[migration v1=>v2] updated %d event entries with codec=0x55", "affected", n) + + var keyRewrites = [][]string{ + {"topic1", "t1"}, + {"topic2", "t2"}, + {"topic3", "t3"}, + {"topic4", "t4"}, + {"data", "d"}, + } + + for _, r := range keyRewrites { + from, to := r[0], r[1] + res, err := tx.Exec(`UPDATE event_entry SET key = ? WHERE key = ?`, to, from) + if err != nil { + return xerrors.Errorf("failed to update entries from key %s to key %s: %w", from, to, err) + } + n, _ := res.RowsAffected() + log.Warnw("[migration v1=>v2] rewrote entry keys", "from", from, "to", to, "affected", n) + } + + update, err := tx.Prepare(`UPDATE event_entry SET value = ? WHERE value = ?`) + if err != nil { + return xerrors.Errorf("failed to prepare update statement: %w", err) + } + + log.Warnw("[migration v1=>v2] processing values") + + topics := map[string]struct{}{ + "t1": {}, + "t2": {}, + "t3": {}, + "t4": {}, + } + + if _, err = tx.Exec(`CREATE TABLE tmp AS SELECT key, value FROM event_entry`); err != nil { + return xerrors.Errorf("failed to create temporary table: %w", err) + } + + // Pull the values out and process them in Go land before updating. + rows, err := tx.Query(`SELECT key, value FROM tmp`) + if err != nil { + return xerrors.Errorf("failed to select values: %w", err) + } + + var i int + for rows.Next() { + var key string + var before []byte + if err := rows.Scan(&key, &before); err != nil { + return xerrors.Errorf("failed to scan from query: %w", err) + } + after, err := cbg.ReadByteArray(bytes.NewReader(before), 4<<20) + if err != nil { + return xerrors.Errorf("failed to decode cbor: %w; value: %s", err, hex.EncodeToString(before)) + } + if _, ok := topics[key]; ok && len(before) < 32 { + // if this is a topic, leftpad to 32 bytes + pvalue := make([]byte, 32) + copy(pvalue[32-len(after):], after) + after = pvalue + } + if _, err := update.Exec(after, before); err != nil { + return xerrors.Errorf("failed to scan from query: %w", err) + } + + if i++; i%500 == 0 { + log.Warnw("[migration v1=>v2] processed values", "count", i) + } + } + + log.Warnw("[migration v1=>v2] processed all values", "count", i) + + if _, err = tx.Exec(`DROP TABLE tmp`); err != nil { + return xerrors.Errorf("failed to drop temporary table: %w", err) + } + + log.Warnw("[migration v1=>v2] dropped temporary table") + + if _, err = tx.Exec(`INSERT INTO _meta (version) VALUES (2)`); err != nil { + return xerrors.Errorf("failed to update schema version: %w", err) + } + + log.Warnw("[migration v1=>v2] schema version updated to v2") + + if err := tx.Commit(); err != nil { + return xerrors.Errorf("failed to commit transaction: %w", err) + } + + log.Warnw("[migration v1=>v2] transaction committed; ALL DONE") + + return nil +} diff --git a/chain/messagepool/messagepool.go b/chain/messagepool/messagepool.go index dabd2cb33..e3354d3e6 100644 --- a/chain/messagepool/messagepool.go +++ b/chain/messagepool/messagepool.go @@ -794,7 +794,12 @@ func (mp *MessagePool) VerifyMsgSig(m *types.SignedMessage) error { return nil } - if err := chain.AuthenticateMessage(m, m.Message.From); err != nil { + nv, err := mp.getNtwkVersion(mp.curTs.Height()) + if err != nil { + return xerrors.Errorf("failedl to get network version: %w", err) + } + + if err := chain.AuthenticateMessage(m, m.Message.From, nv); err != nil { return xerrors.Errorf("failed to validate signature: %w", err) } diff --git a/chain/signatures.go b/chain/signatures.go index 1dc67fd2c..72cbab3e6 100644 --- a/chain/signatures.go +++ b/chain/signatures.go @@ -4,6 +4,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" + "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/network" @@ -16,21 +17,36 @@ import ( // SignedMessage was signed by the indicated Address, computing the correct // signature payload depending on the signature type. The supplied Address type // must be recognized by the registered verifier for the signature type. -func AuthenticateMessage(msg *types.SignedMessage, signer address.Address) error { +func AuthenticateMessage(msg *types.SignedMessage, signer address.Address, nv network.Version) error { var digest []byte typ := msg.Signature.Type switch typ { case crypto.SigTypeDelegated: + if nv >= network.Version20 && msg.Message.Method == builtin.MethodSend { + return xerrors.Errorf("nv20 and above no longer admits method 0 on messages with Ethereum delegated signatures") + } txArgs, err := ethtypes.EthTxArgsFromUnsignedEthMessage(&msg.Message) if err != nil { return xerrors.Errorf("failed to reconstruct eth transaction: %w", err) } + + // Prior to nv20, we rejected empty initcode. + if len(txArgs.Input) == 0 && nv < network.Version20 && txArgs.To == nil { + return xerrors.Errorf("nv19 and below don't support empty initcode") + } + roundTripMsg, err := txArgs.ToUnsignedMessage(msg.Message.From) if err != nil { return xerrors.Errorf("failed to reconstruct filecoin msg: %w", err) } + // Prior to nv20, delegated signature messages with no parameters carried MethodSend. + // Reset the value so we'll roundtrip. + if nv < network.Version20 && roundTripMsg.Method == builtin.MethodsEVM.InvokeContract && len(roundTripMsg.Params) == 0 { + roundTripMsg.Method = builtin.MethodSend + } + if !msg.Message.Equals(roundTripMsg) { return xerrors.New("ethereum tx failed to roundtrip") } diff --git a/chain/state/statetree.go b/chain/state/statetree.go index 7a5908c08..3142a07d8 100644 --- a/chain/state/statetree.go +++ b/chain/state/statetree.go @@ -156,7 +156,7 @@ func VersionForNetwork(ver network.Version) (types.StateTreeVersion, error) { case network.Version13, network.Version14, network.Version15, network.Version16, network.Version17: return types.StateTreeVersion4, nil - case network.Version18, network.Version19: + case network.Version18, network.Version19, network.Version20: return types.StateTreeVersion5, nil default: diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index ea2758705..901fc2d12 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -31,6 +31,10 @@ var ErrExpensiveFork = errors.New("refusing explicit call due to state fork at e // tipset's parent. In the presence of null blocks, the height at which the message is invoked may // be less than the specified tipset. func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types.TipSet) (*api.InvocResult, error) { + // Copy the message as we modify it below. + msgCopy := *msg + msg = &msgCopy + if msg.GasLimit == 0 { msg.GasLimit = build.BlockGasLimit } diff --git a/chain/types/cbor_gen.go b/chain/types/cbor_gen.go index 314b2be6c..fd2462756 100644 --- a/chain/types/cbor_gen.go +++ b/chain/types/cbor_gen.go @@ -2078,3 +2078,224 @@ func (t *EventEntry) UnmarshalCBOR(r io.Reader) (err error) { } return nil } + +var lengthBufLegacyEvent = []byte{130} + +func (t *LegacyEvent) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufLegacyEvent); err != nil { + return err + } + + // t.Emitter (abi.ActorID) (uint64) + + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Emitter)); err != nil { + return err + } + + // t.Entries ([]types.LegacyEventEntry) (slice) + if len(t.Entries) > cbg.MaxLength { + return xerrors.Errorf("Slice value in field t.Entries was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Entries))); err != nil { + return err + } + for _, v := range t.Entries { + if err := v.MarshalCBOR(cw); err != nil { + return err + } + } + return nil +} + +func (t *LegacyEvent) UnmarshalCBOR(r io.Reader) (err error) { + *t = LegacyEvent{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 2 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Emitter (abi.ActorID) (uint64) + + { + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint64 field") + } + t.Emitter = abi.ActorID(extra) + + } + // t.Entries ([]types.LegacyEventEntry) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.MaxLength { + return fmt.Errorf("t.Entries: array too large (%d)", extra) + } + + if maj != cbg.MajArray { + return fmt.Errorf("expected cbor array") + } + + if extra > 0 { + t.Entries = make([]LegacyEventEntry, extra) + } + + for i := 0; i < int(extra); i++ { + + var v LegacyEventEntry + if err := v.UnmarshalCBOR(cr); err != nil { + return err + } + + t.Entries[i] = v + } + + return nil +} + +var lengthBufLegacyEventEntry = []byte{131} + +func (t *LegacyEventEntry) MarshalCBOR(w io.Writer) error { + if t == nil { + _, err := w.Write(cbg.CborNull) + return err + } + + cw := cbg.NewCborWriter(w) + + if _, err := cw.Write(lengthBufLegacyEventEntry); err != nil { + return err + } + + // t.Flags (uint8) (uint8) + if err := cw.WriteMajorTypeHeader(cbg.MajUnsignedInt, uint64(t.Flags)); err != nil { + return err + } + + // t.Key (string) (string) + if len(t.Key) > cbg.MaxLength { + return xerrors.Errorf("Value in field t.Key was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(t.Key))); err != nil { + return err + } + if _, err := io.WriteString(w, string(t.Key)); err != nil { + return err + } + + // t.Value ([]uint8) (slice) + if len(t.Value) > cbg.ByteArrayMaxLen { + return xerrors.Errorf("Byte array in field t.Value was too long") + } + + if err := cw.WriteMajorTypeHeader(cbg.MajByteString, uint64(len(t.Value))); err != nil { + return err + } + + if _, err := cw.Write(t.Value[:]); err != nil { + return err + } + return nil +} + +func (t *LegacyEventEntry) UnmarshalCBOR(r io.Reader) (err error) { + *t = LegacyEventEntry{} + + cr := cbg.NewCborReader(r) + + maj, extra, err := cr.ReadHeader() + if err != nil { + return err + } + defer func() { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } + }() + + if maj != cbg.MajArray { + return fmt.Errorf("cbor input should be of type array") + } + + if extra != 3 { + return fmt.Errorf("cbor input had wrong number of fields") + } + + // t.Flags (uint8) (uint8) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + if maj != cbg.MajUnsignedInt { + return fmt.Errorf("wrong type for uint8 field") + } + if extra > math.MaxUint8 { + return fmt.Errorf("integer in input was too large for uint8 field") + } + t.Flags = uint8(extra) + // t.Key (string) (string) + + { + sval, err := cbg.ReadString(cr) + if err != nil { + return err + } + + t.Key = string(sval) + } + // t.Value ([]uint8) (slice) + + maj, extra, err = cr.ReadHeader() + if err != nil { + return err + } + + if extra > cbg.ByteArrayMaxLen { + return fmt.Errorf("t.Value: byte array too large (%d)", extra) + } + if maj != cbg.MajByteString { + return fmt.Errorf("expected byte array") + } + + if extra > 0 { + t.Value = make([]uint8, extra) + } + + if _, err := io.ReadFull(cr, t.Value[:]); err != nil { + return err + } + return nil +} diff --git a/chain/types/ethtypes/eth_transactions.go b/chain/types/ethtypes/eth_transactions.go index 7c065928e..2eabde6e5 100644 --- a/chain/types/ethtypes/eth_transactions.go +++ b/chain/types/ethtypes/eth_transactions.go @@ -12,6 +12,7 @@ import ( "github.com/filecoin-project/go-address" gocrypto "github.com/filecoin-project/go-crypto" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtintypes "github.com/filecoin-project/go-state-types/builtin" typescrypto "github.com/filecoin-project/go-state-types/crypto" @@ -38,11 +39,19 @@ type EthTx struct { MaxFeePerGas EthBigInt `json:"maxFeePerGas"` MaxPriorityFeePerGas EthBigInt `json:"maxPriorityFeePerGas"` AccessList []EthHash `json:"accessList"` - V EthBigInt `json:"yParity"` + V EthBigInt `json:"v"` R EthBigInt `json:"r"` S EthBigInt `json:"s"` } +func (tx *EthTx) Reward(blkBaseFee big.Int) EthBigInt { + availablePriorityFee := big.Sub(big.Int(tx.MaxFeePerGas), blkBaseFee) + if big.Cmp(big.Int(tx.MaxPriorityFeePerGas), availablePriorityFee) <= 0 { + return tx.MaxPriorityFeePerGas + } + return EthBigInt(availablePriorityFee) +} + type EthTxArgs struct { ChainID int `json:"chainId"` Nonce int `json:"nonce"` @@ -97,49 +106,51 @@ func EthTxFromSignedEthMessage(smsg *types.SignedMessage) (EthTx, error) { func EthTxArgsFromUnsignedEthMessage(msg *types.Message) (EthTxArgs, error) { var ( - to *EthAddress - params []byte - paramsReader = bytes.NewReader(msg.Params) - err error + to *EthAddress + params []byte + err error ) if msg.Version != 0 { return EthTxArgs{}, xerrors.Errorf("unsupported msg version: %d", msg.Version) } + if len(msg.Params) > 0 { + paramsReader := bytes.NewReader(msg.Params) + params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) + if err != nil { + return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err) + } + if paramsReader.Len() != 0 { + return EthTxArgs{}, xerrors.Errorf("extra data found in params") + } + if len(params) == 0 { + return EthTxArgs{}, xerrors.Errorf("non-empty params encode empty byte array") + } + } + if msg.To == builtintypes.EthereumAddressManagerActorAddr { - switch msg.Method { - case builtintypes.MethodsEAM.CreateExternal: - params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) - if err != nil { - return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err) - } - default: + if msg.Method != builtintypes.MethodsEAM.CreateExternal { return EthTxArgs{}, fmt.Errorf("unsupported EAM method") } - } else if msg.Method == builtintypes.MethodsEVM.InvokeContract { + } else if msg.Method == builtintypes.MethodsEVM.InvokeContract || msg.Method == builtintypes.MethodSend { + // < nv20 (Hyperspace): The condition here is technically too lenient. + // The correct behavior would be to _only_ allow MethodSend on < nv20. + // However, snaking through the network version here is too expensive, and not worth it, + // given that the transition period will only last for ~24h anyway. + // AuthenticateMessage is the _crucial_ spot, and it's already applying a stricter check. + // The Eth API endpoint is also selecting the right method depending on the network version. addr, err := EthAddressFromFilecoinAddress(msg.To) if err != nil { return EthTxArgs{}, err } to = &addr - - if len(msg.Params) > 0 { - params, err = cbg.ReadByteArray(paramsReader, uint64(len(msg.Params))) - if err != nil { - return EthTxArgs{}, xerrors.Errorf("failed to read params byte array: %w", err) - } - } } else { return EthTxArgs{}, xerrors.Errorf("invalid methodnum %d: only allowed method is InvokeContract(%d)", msg.Method, builtintypes.MethodsEVM.InvokeContract) } - if paramsReader.Len() != 0 { - return EthTxArgs{}, xerrors.Errorf("extra data found in params") - } - return EthTxArgs{ ChainID: build.Eip155ChainId, Nonce: int(msg.Nonce), @@ -159,34 +170,26 @@ func (tx *EthTxArgs) ToUnsignedMessage(from address.Address) (*types.Message, er var err error var params []byte - var to address.Address - method := builtintypes.MethodsEVM.InvokeContract - // nil indicates the EAM, only CreateExternal is allowed - if tx.To == nil { - to = builtintypes.EthereumAddressManagerActorAddr - method = builtintypes.MethodsEAM.CreateExternal - if len(tx.Input) == 0 { - return nil, xerrors.New("cannot call CreateExternal without params") - } - + if len(tx.Input) > 0 { buf := new(bytes.Buffer) if err = cbg.WriteByteArray(buf, tx.Input); err != nil { - return nil, xerrors.Errorf("failed to serialize Create params: %w", err) + return nil, xerrors.Errorf("failed to write input args: %w", err) } - params = buf.Bytes() + } + + var to address.Address + var method abi.MethodNum + // nil indicates the EAM, only CreateExternal is allowed + if tx.To == nil { + method = builtintypes.MethodsEAM.CreateExternal + to = builtintypes.EthereumAddressManagerActorAddr } else { + method = builtintypes.MethodsEVM.InvokeContract to, err = tx.To.ToFilecoinAddress() if err != nil { return nil, xerrors.Errorf("failed to convert To into filecoin addr: %w", err) } - if len(tx.Input) > 0 { - buf := new(bytes.Buffer) - if err = cbg.WriteByteArray(buf, tx.Input); err != nil { - return nil, xerrors.Errorf("failed to write input args: %w", err) - } - params = buf.Bytes() - } } return &types.Message{ diff --git a/chain/types/event.go b/chain/types/event.go index 91b0e95d3..106a120e2 100644 --- a/chain/types/event.go +++ b/chain/types/event.go @@ -1,11 +1,6 @@ package types import ( - "bytes" - "fmt" - - cbg "github.com/whyrusleeping/cbor-gen" - "github.com/filecoin-project/go-state-types/abi" ) @@ -38,24 +33,3 @@ type EventEntry struct { } type FilterID [32]byte // compatible with EthHash - -// DecodeEvents decodes a CBOR list of CBOR-encoded events. -func DecodeEvents(input []byte) ([]Event, error) { - r := bytes.NewReader(input) - typ, len, err := cbg.NewCborReader(r).ReadHeader() - if err != nil { - return nil, fmt.Errorf("failed to read events: %w", err) - } - if typ != cbg.MajArray { - return nil, fmt.Errorf("expected a CBOR list, was major type %d", typ) - } - events := make([]Event, 0, len) - for i := 0; i < int(len); i++ { - var evt Event - if err := evt.UnmarshalCBOR(r); err != nil { - return nil, fmt.Errorf("failed to parse event: %w", err) - } - events = append(events, evt) - } - return events, nil -} diff --git a/chain/types/legacy_event.go b/chain/types/legacy_event.go new file mode 100644 index 000000000..d37a19585 --- /dev/null +++ b/chain/types/legacy_event.go @@ -0,0 +1,91 @@ +package types + +import ( + "bytes" + "fmt" + + "github.com/multiformats/go-multicodec" + cbg "github.com/whyrusleeping/cbor-gen" + + "github.com/filecoin-project/go-state-types/abi" +) + +type LegacyEvent struct { + // The ID of the actor that emitted this event. + Emitter abi.ActorID + + // Key values making up this event. + Entries []LegacyEventEntry +} + +type LegacyEventEntry struct { + // A bitmap conveying metadata or hints about this entry. + Flags uint8 + + // The key of this event entry + Key string + + // The event value + Value []byte +} + +var keyRewrites = map[string]string{ + "topic1": "t1", + "topic2": "t2", + "topic3": "t3", + "topic4": "t4", + "data": "d", +} + +// Adapt method assumes that all events are EVM events (which is the case for +// nv<20, the network versions for which this code is active), and performs the +// following adaptations: +// - Upgrades the schema to new Events, setting codec = Raw. +// - Removes the CBOR framing from values. +// - Left pads EVM log topic entry values to 32 bytes. +func (e *LegacyEvent) Adapt() (Event, error) { + entries := make([]EventEntry, 0, len(e.Entries)) + for _, ee := range e.Entries { + entry := EventEntry{ + Flags: EventFlagIndexedKey | EventFlagIndexedValue, // override the flags as per final version of FIP-0054 + Key: ee.Key, + Codec: uint64(multicodec.Raw), + Value: ee.Value, + } + var err error + entry.Value, err = cbg.ReadByteArray(bytes.NewReader(ee.Value), 4<<20) + if err != nil { + return Event{}, fmt.Errorf("failed to decode event value while adapting: %w", err) + } + if l := len(entry.Value); l < 32 { + pvalue := make([]byte, 32) + copy(pvalue[32-len(entry.Value):], entry.Value) + entry.Value = pvalue + } + if r, ok := keyRewrites[entry.Key]; ok { + entry.Key = r + } + entries = append(entries, entry) + } + return Event{ + Emitter: e.Emitter, + Entries: entries, + }, nil +} + +// AsLegacy strips the codec off an Event object and returns a LegacyEvent. +func (e *Event) AsLegacy() *LegacyEvent { + entries := make([]LegacyEventEntry, 0, len(e.Entries)) + for _, ee := range e.Entries { + entry := LegacyEventEntry{ + Flags: ee.Flags, + Key: ee.Key, + Value: ee.Value, + } + entries = append(entries, entry) + } + return &LegacyEvent{ + Emitter: e.Emitter, + Entries: entries, + } +} diff --git a/chain/vm/fvm.go b/chain/vm/fvm.go index 8e78e58d9..ffee730d6 100644 --- a/chain/vm/fvm.go +++ b/chain/vm/fvm.go @@ -519,7 +519,7 @@ func (vm *FVM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet } if vm.returnEvents && len(ret.EventsBytes) > 0 { - applyRet.Events, err = types.DecodeEvents(ret.EventsBytes) + applyRet.Events, err = DecodeEvents(ret.EventsBytes) if err != nil { return nil, fmt.Errorf("failed to decode events returned by the FVM: %w", err) } @@ -584,7 +584,7 @@ func (vm *FVM) ApplyImplicitMessage(ctx context.Context, cmsg *types.Message) (* } if vm.returnEvents && len(ret.EventsBytes) > 0 { - applyRet.Events, err = types.DecodeEvents(ret.EventsBytes) + applyRet.Events, err = DecodeEvents(ret.EventsBytes) if err != nil { return nil, fmt.Errorf("failed to decode events returned by the FVM: %w", err) } @@ -707,3 +707,29 @@ func (r *xRedirect) MarshalCBOR(w io.Writer) error { return nil } + +func DecodeEvents(input []byte) ([]cbg.CBORMarshaler, error) { + r := bytes.NewReader(input) + typ, l, err := cbg.NewCborReader(r).ReadHeader() + if err != nil { + return nil, fmt.Errorf("failed to read events: %w", err) + } + if typ != cbg.MajArray { + return nil, fmt.Errorf("expected a CBOR list, was major type %d", typ) + } + + events := make([]cbg.CBORMarshaler, 0, l) + for i := 0; i < int(l); i++ { + var evt types.Event + if err := evt.UnmarshalCBOR(r); err != nil { + return nil, fmt.Errorf("failed to parse event: %w", err) + } + if len(evt.Entries) > 0 && evt.Entries[0].Codec == 0 { + // Codec 0 means this is a legacy event. + events = append(events, evt.AsLegacy()) + } else { + events = append(events, &evt) + } + } + return events, nil +} diff --git a/chain/vm/vm.go b/chain/vm/vm.go index dcebe2b17..62d27ee04 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -284,7 +284,7 @@ type ApplyRet struct { ExecutionTrace types.ExecutionTrace Duration time.Duration GasCosts *GasOutputs - Events []types.Event + Events []cbg.CBORMarshaler } func (vm *LegacyVM) send(ctx context.Context, msg *types.Message, parent *Runtime, diff --git a/chain/vm/vmi.go b/chain/vm/vmi.go index 01b32d4ad..16bc89162 100644 --- a/chain/vm/vmi.go +++ b/chain/vm/vmi.go @@ -4,7 +4,7 @@ import ( "context" "os" - cid "github.com/ipfs/go-cid" + "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/network" diff --git a/cli/evm.go b/cli/evm.go index 39b70672b..f7b77c870 100644 --- a/cli/evm.go +++ b/cli/evm.go @@ -13,13 +13,13 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-address" - amt4 "github.com/filecoin-project/go-amt-ipld/v4" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtintypes "github.com/filecoin-project/go-state-types/builtin" "github.com/filecoin-project/go-state-types/builtin/v10/eam" "github.com/filecoin-project/lotus/api/v0api" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/builtin" "github.com/filecoin-project/lotus/chain/types" @@ -329,7 +329,7 @@ var EvmInvokeCmd = &cli.Command{ Action: func(cctx *cli.Context) error { afmt := NewAppFmt(cctx.App) - api, closer, err := GetFullNodeAPI(cctx) + api, closer, err := GetFullNodeAPIV1(cctx) if err != nil { return err } @@ -390,7 +390,7 @@ var EvmInvokeCmd = &cli.Command{ } afmt.Println("waiting for message to execute...") - wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0) + wait, err := api.StateWaitMsg(ctx, smsg.Cid(), 0, build.Finality, true) if err != nil { return xerrors.Errorf("error waiting for message: %w", err) } @@ -415,37 +415,21 @@ var EvmInvokeCmd = &cli.Command{ if eventsRoot := wait.Receipt.EventsRoot; eventsRoot != nil { afmt.Println("Events emitted:") - s := &apiIpldStore{ctx, api} - amt, err := amt4.LoadAMT(ctx, s, *eventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth)) + events, err := api.ChainGetEvents(ctx, *eventsRoot) if err != nil { - return err + return xerrors.Errorf("failed to get events: %w", err) } - - var evt types.Event - err = amt.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error { - fmt.Printf("%x\n", deferred.Raw) - if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil { - return err - } - if err != nil { - return err - } + for _, evt := range events { fmt.Printf("\tEmitter ID: %s\n", evt.Emitter) for _, e := range evt.Entries { value, err := cbg.ReadByteArray(bytes.NewBuffer(e.Value), uint64(len(e.Value))) if err != nil { return err } - fmt.Printf("\t\tKey: %s, Value: 0x%x, Flags: b%b\n", e.Key, value, e.Flags) + fmt.Printf("\t\tKey: %s, Codec: %d, Value: 0x%x, Flags: b%b\n", e.Key, e.Codec, value, e.Flags) } - return nil - - }) + } } - if err != nil { - return err - } - return nil }, } diff --git a/documentation/en/api-v0-methods-miner.md b/documentation/en/api-v0-methods-miner.md index 969cf82df..448412c63 100644 --- a/documentation/en/api-v0-methods-miner.md +++ b/documentation/en/api-v0-methods-miner.md @@ -474,7 +474,7 @@ Inputs: ], "Bw==", 10101, - 19 + 20 ] ``` diff --git a/documentation/en/api-v0-methods.md b/documentation/en/api-v0-methods.md index c10baca18..9bea4b986 100644 --- a/documentation/en/api-v0-methods.md +++ b/documentation/en/api-v0-methods.md @@ -4727,7 +4727,7 @@ Perms: read Inputs: ```json [ - 19 + 20 ] ``` @@ -4742,7 +4742,7 @@ Perms: read Inputs: ```json [ - 19 + 20 ] ``` @@ -6458,7 +6458,7 @@ Inputs: ] ``` -Response: `19` +Response: `20` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/documentation/en/api-v1-unstable-methods.md b/documentation/en/api-v1-unstable-methods.md index 7c82bce64..02509170a 100644 --- a/documentation/en/api-v1-unstable-methods.md +++ b/documentation/en/api-v1-unstable-methods.md @@ -2643,7 +2643,7 @@ Response: "accessList": [ "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ], - "yParity": "0x0", + "v": "0x0", "r": "0x0", "s": "0x0" } @@ -2682,7 +2682,7 @@ Response: "accessList": [ "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ], - "yParity": "0x0", + "v": "0x0", "r": "0x0", "s": "0x0" } @@ -2720,7 +2720,7 @@ Response: "accessList": [ "0x37690cfec6c1bf4c3b9288c7a5d783e98731e90b0a4c177c2a374c7a9427355e" ], - "yParity": "0x0", + "v": "0x0", "r": "0x0", "s": "0x0" } @@ -5961,7 +5961,7 @@ Perms: read Inputs: ```json [ - 19 + 20 ] ``` @@ -5976,7 +5976,7 @@ Perms: read Inputs: ```json [ - 19 + 20 ] ``` @@ -7775,7 +7775,7 @@ Inputs: ] ``` -Response: `19` +Response: `20` ### StateReadState StateReadState returns the indicated actor's state. diff --git a/extern/filecoin-ffi b/extern/filecoin-ffi index d2e527cf6..fead3c628 160000 --- a/extern/filecoin-ffi +++ b/extern/filecoin-ffi @@ -1 +1 @@ -Subproject commit d2e527cf6881fd4f8a9547f15ffa1674a8004ea3 +Subproject commit fead3c628794a332ebc2ef0a153885bfab87a901 diff --git a/gen/inlinegen-data.json b/gen/inlinegen-data.json index ec55f0d52..b8353b96e 100644 --- a/gen/inlinegen-data.json +++ b/gen/inlinegen-data.json @@ -1,7 +1,7 @@ { - "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], - "latestActorsVersion": 11, + "actorVersions": [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], + "latestActorsVersion": 12, - "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19], - "latestNetworkVersion": 19 + "networkVersions": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], + "latestNetworkVersion": 20 } diff --git a/gen/main.go b/gen/main.go index a3891778a..d4c603ee1 100644 --- a/gen/main.go +++ b/gen/main.go @@ -37,6 +37,8 @@ func main() { types.StateInfo0{}, types.Event{}, types.EventEntry{}, + types.LegacyEvent{}, + types.LegacyEventEntry{}, ) if err != nil { fmt.Println(err) diff --git a/go.mod b/go.mod index e901fb34e..6aadba214 100644 --- a/go.mod +++ b/go.mod @@ -44,7 +44,7 @@ require ( github.com/filecoin-project/go-legs v0.4.4 github.com/filecoin-project/go-padreader v0.0.1 github.com/filecoin-project/go-paramfetch v0.0.4 - github.com/filecoin-project/go-state-types v0.10.0-rc2 + github.com/filecoin-project/go-state-types v0.10.0-rc2.0.20230213183937-7f1ede218b87 github.com/filecoin-project/go-statemachine v1.0.2 github.com/filecoin-project/go-statestore v0.2.0 github.com/filecoin-project/go-storedcounter v0.1.0 @@ -110,7 +110,7 @@ require ( github.com/ipld/go-car v0.4.0 github.com/ipld/go-car/v2 v2.5.0 github.com/ipld/go-codec-dagpb v1.5.0 - github.com/ipld/go-ipld-prime v0.18.0 + github.com/ipld/go-ipld-prime v0.20.0 github.com/ipld/go-ipld-selector-text-lite v0.0.1 github.com/kelseyhightower/envconfig v1.4.0 github.com/koalacxr/quantile v0.0.1 @@ -133,6 +133,7 @@ require ( github.com/multiformats/go-multiaddr v0.7.0 github.com/multiformats/go-multiaddr-dns v0.3.1 github.com/multiformats/go-multibase v0.1.1 + github.com/multiformats/go-multicodec v0.8.0 github.com/multiformats/go-multihash v0.2.1 github.com/multiformats/go-varint v0.0.6 github.com/open-rpc/meta-schema v0.0.0-20201029221707-1b72ef2ea333 @@ -294,7 +295,6 @@ require ( github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect - github.com/multiformats/go-multicodec v0.6.0 // indirect github.com/multiformats/go-multistream v0.3.3 // indirect github.com/nikkolasg/hexjson v0.0.0-20181101101858-78e39397e00c // indirect github.com/nkovacs/streamquote v1.0.0 // indirect diff --git a/go.sum b/go.sum index 997ac3335..28790cad8 100644 --- a/go.sum +++ b/go.sum @@ -356,8 +356,8 @@ github.com/filecoin-project/go-state-types v0.1.0/go.mod h1:ezYnPf0bNkTsDibL/psS github.com/filecoin-project/go-state-types v0.1.6/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.8/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= github.com/filecoin-project/go-state-types v0.1.10/go.mod h1:UwGVoMsULoCK+bWjEdd/xLCvLAQFBC7EDT477SKml+Q= -github.com/filecoin-project/go-state-types v0.10.0-rc2 h1:nl92h86XridAoy0fjvW+8/8/eI0caVSm0fhAnIvtR64= -github.com/filecoin-project/go-state-types v0.10.0-rc2/go.mod h1:aLIas+W8BWAfpLWEPUOGMPBdhcVwoCG4pIQSQk26024= +github.com/filecoin-project/go-state-types v0.10.0-rc2.0.20230213183937-7f1ede218b87 h1:gqKaMwXp8mrvf1Zj+l8mXUPTC2HYf+TG7rcSivO0nDI= +github.com/filecoin-project/go-state-types v0.10.0-rc2.0.20230213183937-7f1ede218b87/go.mod h1:aLIas+W8BWAfpLWEPUOGMPBdhcVwoCG4pIQSQk26024= github.com/filecoin-project/go-statemachine v0.0.0-20200925024713-05bd7c71fbfe/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v1.0.2 h1:421SSWBk8GIoCoWYYTE/d+qCWccgmRH0uXotXRDjUbc= github.com/filecoin-project/go-statemachine v1.0.2/go.mod h1:jZdXXiHa61n4NmgWFG4w8tnqgvZVHYbJ3yW7+y8bF54= @@ -403,8 +403,8 @@ github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2 github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.2/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= -github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= @@ -899,8 +899,8 @@ github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHt github.com/ipld/go-ipld-prime v0.14.0/go.mod h1:9ASQLwUFLptCov6lIYc70GRB4V7UTyLD0IJtrDJe6ZM= github.com/ipld/go-ipld-prime v0.16.0/go.mod h1:axSCuOCBPqrH+gvXr2w9uAOulJqBPhHPT2PjoiiU1qA= github.com/ipld/go-ipld-prime v0.17.0/go.mod h1:aYcKm5TIvGfY8P3QBKz/2gKcLxzJ1zDaD+o0bOowhgs= -github.com/ipld/go-ipld-prime v0.18.0 h1:xUk7NUBSWHEXdjiOu2sLXouFJOMs0yoYzeI5RAqhYQo= -github.com/ipld/go-ipld-prime v0.18.0/go.mod h1:735yXW548CKrLwVCYXzqx90p5deRJMVVxM9eJ4Qe+qE= +github.com/ipld/go-ipld-prime v0.20.0 h1:Ud3VwE9ClxpO2LkCYP7vWPc0Fo+dYdYzgxUJZ3uRG4g= +github.com/ipld/go-ipld-prime v0.20.0/go.mod h1:PzqZ/ZR981eKbgdr3y2DJYeD/8bgMawdGVlJDE8kK+M= github.com/ipld/go-ipld-prime-proto v0.0.0-20191113031812-e32bd156a1e5/go.mod h1:gcvzoEDBjwycpXt3LBE061wT9f46szXGHAmj9uoP6fU= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73 h1:TsyATB2ZRRQGTwafJdgEUQkmjOExRV0DNokcihZxbnQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20211210234204-ce2a1c70cd73/go.mod h1:2PJ0JgxyB08t0b2WKrcuqI3di0V+5n6RS/LTUJhkoxY= @@ -997,8 +997,8 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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= @@ -1523,8 +1523,8 @@ github.com/multiformats/go-multicodec v0.3.1-0.20210902112759-1539a079fd61/go.mo github.com/multiformats/go-multicodec v0.3.1-0.20211210143421-a526f306ed2c/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.4.1/go.mod h1:1Hj/eHRaVWSXiSNNfcEPcwZleTmdNP81xlxDLnWU9GQ= github.com/multiformats/go-multicodec v0.5.0/go.mod h1:DiY2HFaEp5EhEXb/iYzVAunmyX/aSFMxq2KMKfWEues= -github.com/multiformats/go-multicodec v0.6.0 h1:KhH2kSuCARyuJraYMFxrNO3DqIaYhOdS039kbhgVwpE= -github.com/multiformats/go-multicodec v0.6.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= +github.com/multiformats/go-multicodec v0.8.0 h1:evBmgkbSQux+Ds2IgfhkO38Dl2GDtRW8/Rp6YiSHX/Q= +github.com/multiformats/go-multicodec v0.8.0/go.mod h1:GUC8upxSBE4oG+q3kWZRw/+6yC1BqO550bjhWsJbZlw= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.8/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= @@ -1708,7 +1708,7 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L 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= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= @@ -1849,8 +1849,8 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.10.0 h1:E86YlUMYfwIacEsQGlnTvjk1IgYkyTGjPhF0RnwTCmw= github.com/warpfork/go-testmark v0.10.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= +github.com/warpfork/go-testmark v0.11.0 h1:J6LnV8KpceDvo7spaNU4+DauH2n1x+6RaO2rJrmpQ9U= github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= diff --git a/itests/contracts/GetDifficulty.hex b/itests/contracts/GetDifficulty.hex new file mode 100644 index 000000000..6d584b233 --- /dev/null +++ b/itests/contracts/GetDifficulty.hex @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5060b58061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063b6baffe314602d575b600080fd5b60336047565b604051603e91906066565b60405180910390f35b600044905090565b6000819050919050565b606081604f565b82525050565b6000602082019050607960008301846059565b9291505056fea2646970667358221220c113f1abaabaed6a0324d363896b0d15a8bca7b9a540948a5be5b636a12a534f64736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/GetDifficulty.sol b/itests/contracts/GetDifficulty.sol new file mode 100644 index 000000000..155e7cfd1 --- /dev/null +++ b/itests/contracts/GetDifficulty.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.17; + +contract GetDifficulty { + function getDifficulty () public view returns (uint256) { + return block.difficulty; + } +} + diff --git a/itests/contracts/TransparentUpgradeableProxy.hex b/itests/contracts/TransparentUpgradeableProxy.hex new file mode 100644 index 000000000..d3430beee --- /dev/null +++ b/itests/contracts/TransparentUpgradeableProxy.hex @@ -0,0 +1 @@ +608060405234801561001057600080fd5b5061256c806100206000396000f3fe60806040523480156200001157600080fd5b50600436106200003a5760003560e01c806320965255146200003f578063f8a8fd6d1462000061575b600080fd5b620000496200006d565b604051620000589190620002a6565b60405180910390f35b6200006b62000234565b005b6000806040516200007e9062000253565b604051809103906000f0801580156200009b573d6000803e3d6000fd5b509050600081604051620000af9062000261565b620000bb919062000308565b604051809103906000f080158015620000d8573d6000803e3d6000fd5b5090506000604051620000eb906200026f565b604051809103906000f08015801562000108573d6000803e3d6000fd5b5090508173ffffffffffffffffffffffffffffffffffffffff16633659cfe6826040518263ffffffff1660e01b815260040162000146919062000308565b600060405180830381600087803b1580156200016157600080fd5b505af115801562000176573d6000803e3d6000fd5b5050505060006040516200018a906200027d565b604051809103906000f080158015620001a7573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff16633ccc0522846040518263ffffffff1660e01b8152600401620001e5919062000308565b6020604051808303816000875af115801562000205573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200022b91906200035b565b94505050505090565b6200023e6200006d565b6000146200025157620002506200038d565b5b565b6103f780620003bd83390190565b61174480620007b483390190565b6103ef8062001ef883390190565b61025080620022e783390190565b6000819050919050565b620002a0816200028b565b82525050565b6000602082019050620002bd600083018462000295565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620002f082620002c3565b9050919050565b6200030281620002e3565b82525050565b60006020820190506200031f6000830184620002f7565b92915050565b600080fd5b62000335816200028b565b81146200034157600080fd5b50565b60008151905062000355816200032a565b92915050565b60006020828403121562000374576200037362000325565b5b6000620003848482850162000344565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fdfe608060405234801561001057600080fd5b506103d7806100206000396000f3fe608060405234801561001057600080fd5b50600436106100455760003560e01c8063209652551461004e578063552410771461006c5780638129fc1c1461008857610046565b5b600180819055005b610056610092565b6040516100639190610218565b60405180910390f35b61008660048036038101906100819190610264565b61009c565b005b6100906100a6565b005b6000600154905090565b8060018190555050565b60008060019054906101000a900460ff161590508080156100d75750600160008054906101000a900460ff1660ff16105b8061010457506100e6306101dc565b1580156101035750600160008054906101000a900460ff1660ff16145b5b610143576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161013a90610314565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610180576001600060016101000a81548160ff0219169083151502179055505b80156101d95760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516101d09190610386565b60405180910390a15b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000819050919050565b610212816101ff565b82525050565b600060208201905061022d6000830184610209565b92915050565b600080fd5b610241816101ff565b811461024c57600080fd5b50565b60008135905061025e81610238565b92915050565b60006020828403121561027a57610279610233565b5b60006102888482850161024f565b91505092915050565b600082825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006102fe602e83610291565b9150610309826102a2565b604082019050919050565b6000602082019050818103600083015261032d816102f1565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b600061037061036b61036684610334565b61034b565b61033e565b9050919050565b61038081610355565b82525050565b600060208201905061039b6000830184610377565b9291505056fea2646970667358221220934a8ba055f2e0df7da7dde7999f38a4972809a218a2a064683da10ad547f1fd64736f6c63430008110033608060405260405162001744380380620017448339818101604052810190620000299190620005c7565b80604051806020016040528060008152506200004e828260006200006860201b60201c565b50506200006133620000ab60201b60201c565b50620008fd565b62000079836200010960201b60201c565b600082511180620000875750805b15620000a657620000a483836200016060201b620003361760201c565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f620000dc6200019660201b60201c565b82604051620000ed9291906200060a565b60405180910390a16200010681620001fa60201b60201c565b50565b6200011a81620002ea60201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b60606200018e83836040518060600160405280602781526020016200171d60279139620003c060201b60201c565b905092915050565b6000620001d17fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b6200045260201b620003631760201c565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200026c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200026390620006be565b60405180910390fd5b80620002a67fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b6200045260201b620003631760201c565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b62000300816200045c60201b6200036d1760201c565b62000342576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003399062000756565b60405180910390fd5b806200037c7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b6200045260201b620003631760201c565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60606000808573ffffffffffffffffffffffffffffffffffffffff1685604051620003ec9190620007f1565b600060405180830381855af49150503d806000811462000429576040519150601f19603f3d011682016040523d82523d6000602084013e6200042e565b606091505b509150915062000447868383876200047f60201b60201c565b925050509392505050565b6000819050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b60608315620004ef576000835103620004e657620004a3856200045c60201b60201c565b620004e5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004dc906200085a565b60405180910390fd5b5b82905062000502565b6200050183836200050a60201b60201c565b5b949350505050565b6000825111156200051e5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620005549190620008d9565b60405180910390fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200058f8262000562565b9050919050565b620005a18162000582565b8114620005ad57600080fd5b50565b600081519050620005c18162000596565b92915050565b600060208284031215620005e057620005df6200055d565b5b6000620005f084828501620005b0565b91505092915050565b620006048162000582565b82525050565b6000604082019050620006216000830185620005f9565b620006306020830184620005f9565b9392505050565b600082825260208201905092915050565b7f455243313936373a206e65772061646d696e20697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000620006a660268362000637565b9150620006b38262000648565b604082019050919050565b60006020820190508181036000830152620006d98162000697565b9050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b60006200073e602d8362000637565b91506200074b82620006e0565b604082019050919050565b6000602082019050818103600083015262000771816200072f565b9050919050565b600081519050919050565b600081905092915050565b60005b83811015620007ae57808201518184015260208101905062000791565b60008484015250505050565b6000620007c78262000778565b620007d3818562000783565b9350620007e58185602086016200078e565b80840191505092915050565b6000620007ff8284620007ba565b915081905092915050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b600062000842601d8362000637565b91506200084f826200080a565b602082019050919050565b60006020820190508181036000830152620008758162000833565b9050919050565b600081519050919050565b6000601f19601f8301169050919050565b6000620008a5826200087c565b620008b1818562000637565b9350620008c38185602086016200078e565b620008ce8162000887565b840191505092915050565b60006020820190508181036000830152620008f5818462000898565b905092915050565b610e10806200090d6000396000f3fe60806040526004361061004e5760003560e01c80633659cfe6146100675780634f1ef286146100835780635c60da1b1461009f5780638f283970146100bd578063f851a440146100d95761005d565b3661005d5761005b6100f7565b005b6100656100f7565b005b610081600480360381019061007c9190610916565b610111565b005b61009d600480360381019061009891906109a8565b61017f565b005b6100a761021c565b6040516100b49190610a17565b60405180910390f35b6100d760048036038101906100d29190610916565b61027b565b005b6100e16102d7565b6040516100ee9190610a17565b60405180910390f35b6100ff610390565b61010f61010a61040f565b61041e565b565b610119610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036101735761015361049b565b61016e816040518060200160405280600081525060006104aa565b61017c565b61017b6100f7565b5b50565b610187610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff160361020e576102098383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505060016104aa565b610217565b6102166100f7565b5b505050565b6000610226610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff160361026f5761026061049b565b61026861040f565b9050610278565b6102776100f7565b5b90565b610283610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16036102cb576102bd61049b565b6102c6816104d6565b6102d4565b6102d36100f7565b5b50565b60006102e1610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff160361032a5761031b61049b565b610323610444565b9050610333565b6103326100f7565b5b90565b606061035b8383604051806060016040528060278152602001610db460279139610522565b905092915050565b6000819050919050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b610398610444565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1603610405576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103fc90610adb565b60405180910390fd5b61040d6105a8565b565b60006104196105aa565b905090565b3660008037600080366000845af43d6000803e806000811461043f573d6000f35b3d6000fd5b60006104727fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b610363565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600034146104a857600080fd5b565b6104b383610601565b6000825111806104c05750805b156104d1576104cf8383610336565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6104ff610444565b8260405161050e929190610afb565b60405180910390a161051f81610650565b50565b60606000808573ffffffffffffffffffffffffffffffffffffffff168560405161054c9190610b95565b600060405180830381855af49150503d8060008114610587576040519150601f19603f3d011682016040523d82523d6000602084013e61058c565b606091505b509150915061059d86838387610730565b925050509392505050565b565b60006105d87f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b610363565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61060a816107a5565b8073ffffffffffffffffffffffffffffffffffffffff167fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b60405160405180910390a250565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036106bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106b690610c1e565b60405180910390fd5b806106ec7fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610360001b610363565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6060831561079257600083510361078a5761074a8561036d565b610789576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161078090610c8a565b60405180910390fd5b5b82905061079d565b61079c838361085e565b5b949350505050565b6107ae8161036d565b6107ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107e490610d1c565b60405180910390fd5b8061081a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc60001b610363565b60000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000825111156108715781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108a59190610d91565b60405180910390fd5b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006108e3826108b8565b9050919050565b6108f3816108d8565b81146108fe57600080fd5b50565b600081359050610910816108ea565b92915050565b60006020828403121561092c5761092b6108ae565b5b600061093a84828501610901565b91505092915050565b600080fd5b600080fd5b600080fd5b60008083601f84011261096857610967610943565b5b8235905067ffffffffffffffff81111561098557610984610948565b5b6020830191508360018202830111156109a1576109a061094d565b5b9250929050565b6000806000604084860312156109c1576109c06108ae565b5b60006109cf86828701610901565b935050602084013567ffffffffffffffff8111156109f0576109ef6108b3565b5b6109fc86828701610952565b92509250509250925092565b610a11816108d8565b82525050565b6000602082019050610a2c6000830184610a08565b92915050565b600082825260208201905092915050565b7f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60008201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760208201527f6574000000000000000000000000000000000000000000000000000000000000604082015250565b6000610ac5604283610a32565b9150610ad082610a43565b606082019050919050565b60006020820190508181036000830152610af481610ab8565b9050919050565b6000604082019050610b106000830185610a08565b610b1d6020830184610a08565b9392505050565b600081519050919050565b600081905092915050565b60005b83811015610b58578082015181840152602081019050610b3d565b60008484015250505050565b6000610b6f82610b24565b610b798185610b2f565b9350610b89818560208601610b3a565b80840191505092915050565b6000610ba18284610b64565b915081905092915050565b7f455243313936373a206e65772061646d696e20697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000610c08602683610a32565b9150610c1382610bac565b604082019050919050565b60006020820190508181036000830152610c3781610bfb565b9050919050565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b6000610c74601d83610a32565b9150610c7f82610c3e565b602082019050919050565b60006020820190508181036000830152610ca381610c67565b9050919050565b7f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60008201527f6f74206120636f6e747261637400000000000000000000000000000000000000602082015250565b6000610d06602d83610a32565b9150610d1182610caa565b604082019050919050565b60006020820190508181036000830152610d3581610cf9565b9050919050565b600081519050919050565b6000601f19601f8301169050919050565b6000610d6382610d3c565b610d6d8185610a32565b9350610d7d818560208601610b3a565b610d8681610d47565b840191505092915050565b60006020820190508181036000830152610dab8184610d58565b90509291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220e09e1af8aa595ace2cac727dfa78b8a1c201fdfb2f2b3364541017dec279304b64736f6c63430008110033416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564608060405234801561001057600080fd5b506103cf806100206000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063209652551461004657806355241077146100645780638129fc1c14610080575b600080fd5b61004e61008a565b60405161005b9190610210565b60405180910390f35b61007e6004803603810190610079919061025c565b610094565b005b61008861009e565b005b6000600154905090565b8060018190555050565b60008060019054906101000a900460ff161590508080156100cf5750600160008054906101000a900460ff1660ff16105b806100fc57506100de306101d4565b1580156100fb5750600160008054906101000a900460ff1660ff16145b5b61013b576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101329061030c565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610178576001600060016101000a81548160ff0219169083151502179055505b80156101d15760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb384740249860016040516101c8919061037e565b60405180910390a15b50565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000819050919050565b61020a816101f7565b82525050565b60006020820190506102256000830184610201565b92915050565b600080fd5b610239816101f7565b811461024457600080fd5b50565b60008135905061025681610230565b92915050565b6000602082840312156102725761027161022b565b5b600061028084828501610247565b91505092915050565b600082825260208201905092915050565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b60006102f6602e83610289565b91506103018261029a565b604082019050919050565b60006020820190508181036000830152610325816102e9565b9050919050565b6000819050919050565b600060ff82169050919050565b6000819050919050565b600061036861036361035e8461032c565b610343565b610336565b9050919050565b6103788161034d565b82525050565b6000602082019050610393600083018461036f565b9291505056fea2646970667358221220f2a2169e9ff5b35281e8323276adc729174eda42cfb39d55a7943efc6c70485164736f6c63430008110033608060405234801561001057600080fd5b50610230806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80633ccc052214610030575b600080fd5b61004a60048036038101906100459190610140565b610060565b6040516100579190610186565b60405180910390f35b6000808290508073ffffffffffffffffffffffffffffffffffffffff1663209652556040518163ffffffff1660e01b8152600401602060405180830381865afa1580156100b1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100d591906101cd565b915050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061010d826100e2565b9050919050565b61011d81610102565b811461012857600080fd5b50565b60008135905061013a81610114565b92915050565b600060208284031215610156576101556100dd565b5b60006101648482850161012b565b91505092915050565b6000819050919050565b6101808161016d565b82525050565b600060208201905061019b6000830184610177565b92915050565b6101aa8161016d565b81146101b557600080fd5b50565b6000815190506101c7816101a1565b92915050565b6000602082840312156101e3576101e26100dd565b5b60006101f1848285016101b8565b9150509291505056fea2646970667358221220b98dab0efb759c0eea90d951be7f01d309e1c04588076d429d10680bddf1351864736f6c63430008110033a264697066735822122024666606126645f287960fe9548cc80d17258ad514d74180c7af0e1ee954bd4364736f6c63430008110033 \ No newline at end of file diff --git a/itests/contracts/TransparentUpgradeableProxy.sol b/itests/contracts/TransparentUpgradeableProxy.sol new file mode 100644 index 000000000..5bb3d0e5d --- /dev/null +++ b/itests/contracts/TransparentUpgradeableProxy.sol @@ -0,0 +1,590 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +abstract contract Initializable { + uint8 private _initialized; + + bool private _initializing; + + event Initialized(uint8 version); + + modifier initializer() { + bool isTopLevelCall = !_initializing; + require( + (isTopLevelCall && _initialized < 1) || + (!Address.isContract(address(this)) && _initialized == 1), + "Initializable: contract is already initialized" + ); + _initialized = 1; + if (isTopLevelCall) { + _initializing = true; + } + _; + if (isTopLevelCall) { + _initializing = false; + emit Initialized(1); + } + } + + modifier reinitializer(uint8 version) { + require( + !_initializing && _initialized < version, + "Initializable: contract is already initialized" + ); + _initialized = version; + _initializing = true; + _; + _initializing = false; + emit Initialized(version); + } + + modifier onlyInitializing() { + require(_initializing, "Initializable: contract is not initializing"); + _; + } + + function _disableInitializers() internal virtual { + require(!_initializing, "Initializable: contract is initializing"); + if (_initialized != type(uint8).max) { + _initialized = type(uint8).max; + emit Initialized(type(uint8).max); + } + } + + function _getInitializedVersion() internal view returns (uint8) { + return _initialized; + } + + function _isInitializing() internal view returns (bool) { + return _initializing; + } +} + +contract Implementation4 is Initializable { + uint256 internal _value; + + function initialize() public initializer {} + + function setValue(uint256 _number) public { + _value = _number; + } + + function getValue() public view returns (uint256) { + return _value; + } + + fallback() external { + _value = 1; + } +} + +contract Implementation2 is Initializable { + uint256 internal _value; + + function initialize() public initializer {} + + function setValue(uint256 _number) public { + _value = _number; + } + + function getValue() public view returns (uint256) { + return _value; + } +} + +abstract contract Proxy { + function _delegate(address implementation) internal virtual { + assembly { + calldatacopy(0, 0, calldatasize()) + + let result := delegatecall( + gas(), + implementation, + 0, + calldatasize(), + 0, + 0 + ) + + returndatacopy(0, 0, returndatasize()) + + switch result + case 0 { + revert(0, returndatasize()) + } + default { + return(0, returndatasize()) + } + } + } + + function _implementation() internal view virtual returns (address); + + function _fallback() internal virtual { + _beforeFallback(); + _delegate(_implementation()); + } + + fallback() external payable virtual { + _fallback(); + } + + receive() external payable virtual { + _fallback(); + } + + function _beforeFallback() internal virtual {} +} + +interface IBeacon { + function implementation() external view returns (address); +} + +interface IERC1822Proxiable { + function proxiableUUID() external view returns (bytes32); +} + +library Address { + function isContract(address account) internal view returns (bool) { + return account.code.length > 0; + } + + function sendValue(address payable recipient, uint256 amount) internal { + require( + address(this).balance >= amount, + "Address: insufficient balance" + ); + + (bool success, ) = recipient.call{value: amount}(""); + require( + success, + "Address: unable to send value, recipient may have reverted" + ); + } + + function functionCall( + address target, + bytes memory data + ) internal returns (bytes memory) { + return + functionCallWithValue( + target, + data, + 0, + "Address: low-level call failed" + ); + } + + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + return functionCallWithValue(target, data, 0, errorMessage); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { + return + functionCallWithValue( + target, + data, + value, + "Address: low-level call with value failed" + ); + } + + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { + require( + address(this).balance >= value, + "Address: insufficient balance for call" + ); + (bool success, bytes memory returndata) = target.call{value: value}( + data + ); + return + verifyCallResultFromTarget( + target, + success, + returndata, + errorMessage + ); + } + + function functionStaticCall( + address target, + bytes memory data + ) internal view returns (bytes memory) { + return + functionStaticCall( + target, + data, + "Address: low-level static call failed" + ); + } + + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { + (bool success, bytes memory returndata) = target.staticcall(data); + return + verifyCallResultFromTarget( + target, + success, + returndata, + errorMessage + ); + } + + function functionDelegateCall( + address target, + bytes memory data + ) internal returns (bytes memory) { + return + functionDelegateCall( + target, + data, + "Address: low-level delegate call failed" + ); + } + + function functionDelegateCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { + (bool success, bytes memory returndata) = target.delegatecall(data); + return + verifyCallResultFromTarget( + target, + success, + returndata, + errorMessage + ); + } + + function verifyCallResultFromTarget( + address target, + bool success, + bytes memory returndata, + string memory errorMessage + ) internal view returns (bytes memory) { + if (success) { + if (returndata.length == 0) { + require(isContract(target), "Address: call to non-contract"); + } + return returndata; + } else { + _revert(returndata, errorMessage); + } + } + + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { + if (success) { + return returndata; + } else { + _revert(returndata, errorMessage); + } + } + + function _revert( + bytes memory returndata, + string memory errorMessage + ) private pure { + if (returndata.length > 0) { + assembly { + let returndata_size := mload(returndata) + revert(add(32, returndata), returndata_size) + } + } else { + revert(errorMessage); + } + } +} + +library StorageSlot { + struct AddressSlot { + address value; + } + + struct BooleanSlot { + bool value; + } + + struct Bytes32Slot { + bytes32 value; + } + + struct Uint256Slot { + uint256 value; + } + + function getAddressSlot( + bytes32 slot + ) internal pure returns (AddressSlot storage r) { + assembly { + r.slot := slot + } + } + + function getBooleanSlot( + bytes32 slot + ) internal pure returns (BooleanSlot storage r) { + assembly { + r.slot := slot + } + } + + function getBytes32Slot( + bytes32 slot + ) internal pure returns (Bytes32Slot storage r) { + assembly { + r.slot := slot + } + } + + function getUint256Slot( + bytes32 slot + ) internal pure returns (Uint256Slot storage r) { + assembly { + r.slot := slot + } + } +} + +abstract contract ERC1967Upgrade { + bytes32 private constant _ROLLBACK_SLOT = + 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; + + bytes32 internal constant _IMPLEMENTATION_SLOT = + 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; + + event Upgraded(address indexed implementation); + + function _getImplementation() internal view returns (address) { + return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; + } + + function _setImplementation(address newImplementation) private { + require( + Address.isContract(newImplementation), + "ERC1967: new implementation is not a contract" + ); + StorageSlot + .getAddressSlot(_IMPLEMENTATION_SLOT) + .value = newImplementation; + } + + function _upgradeTo(address newImplementation) internal { + _setImplementation(newImplementation); + emit Upgraded(newImplementation); + } + + function _upgradeToAndCall( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + _upgradeTo(newImplementation); + if (data.length > 0 || forceCall) { + Address.functionDelegateCall(newImplementation, data); + } + } + + function _upgradeToAndCallUUPS( + address newImplementation, + bytes memory data, + bool forceCall + ) internal { + if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) { + _setImplementation(newImplementation); + } else { + try IERC1822Proxiable(newImplementation).proxiableUUID() returns ( + bytes32 slot + ) { + require( + slot == _IMPLEMENTATION_SLOT, + "ERC1967Upgrade: unsupported proxiableUUID" + ); + } catch { + revert("ERC1967Upgrade: new implementation is not UUPS"); + } + _upgradeToAndCall(newImplementation, data, forceCall); + } + } + + bytes32 internal constant _ADMIN_SLOT = + 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; + + event AdminChanged(address previousAdmin, address newAdmin); + + function _getAdmin() internal view returns (address) { + return StorageSlot.getAddressSlot(_ADMIN_SLOT).value; + } + + function _setAdmin(address newAdmin) private { + require( + newAdmin != address(0), + "ERC1967: new admin is the zero address" + ); + StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin; + } + + function _changeAdmin(address newAdmin) internal { + emit AdminChanged(_getAdmin(), newAdmin); + _setAdmin(newAdmin); + } + + bytes32 internal constant _BEACON_SLOT = + 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; + + event BeaconUpgraded(address indexed beacon); + + function _getBeacon() internal view returns (address) { + return StorageSlot.getAddressSlot(_BEACON_SLOT).value; + } + + function _setBeacon(address newBeacon) private { + require( + Address.isContract(newBeacon), + "ERC1967: new beacon is not a contract" + ); + require( + Address.isContract(IBeacon(newBeacon).implementation()), + "ERC1967: beacon implementation is not a contract" + ); + StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon; + } + + function _upgradeBeaconToAndCall( + address newBeacon, + bytes memory data, + bool forceCall + ) internal { + _setBeacon(newBeacon); + emit BeaconUpgraded(newBeacon); + if (data.length > 0 || forceCall) { + Address.functionDelegateCall( + IBeacon(newBeacon).implementation(), + data + ); + } + } +} + +contract ERC1967Proxy is Proxy, ERC1967Upgrade { + constructor(address _logic, bytes memory _data) payable { + _upgradeToAndCall(_logic, _data, false); + } + + function _implementation() + internal + view + virtual + override + returns (address impl) + { + return ERC1967Upgrade._getImplementation(); + } +} + +contract TransparentUpgradeableProxy is ERC1967Proxy { + constructor(address _logic) payable ERC1967Proxy(_logic, "") { + _changeAdmin(msg.sender); + } + + modifier ifAdmin() { + if (msg.sender == _getAdmin()) { + _; + } else { + _fallback(); + } + } + + function admin() external payable ifAdmin returns (address admin_) { + _requireZeroValue(); + admin_ = _getAdmin(); + } + + function implementation() + external + payable + ifAdmin + returns (address implementation_) + { + _requireZeroValue(); + implementation_ = _implementation(); + } + + function changeAdmin(address newAdmin) external payable virtual ifAdmin { + _requireZeroValue(); + _changeAdmin(newAdmin); + } + + function upgradeTo(address newImplementation) external payable ifAdmin { + _requireZeroValue(); + _upgradeToAndCall(newImplementation, bytes(""), false); + } + + function upgradeToAndCall( + address newImplementation, + bytes calldata data + ) external payable ifAdmin { + _upgradeToAndCall(newImplementation, data, true); + } + + function _admin() internal view virtual returns (address) { + return _getAdmin(); + } + + function _beforeFallback() internal virtual override { + require( + msg.sender != _getAdmin(), + "TransparentUpgradeableProxy: admin cannot fallback to proxy target" + ); + super._beforeFallback(); + } + + function _requireZeroValue() private { + require(msg.value == 0); + } +} + +contract TestHelper { + function getValue(address proxyAddress) public returns (uint256) { + Implementation2 proxyInstance2 = Implementation2(proxyAddress); + return proxyInstance2.getValue(); + } +} + +contract TransparentUpgradeableProxyTestRunner { + function test() public { + assert(0 == getValue()); + } + + function getValue() public returns (uint256) { + Implementation4 instance4 = new Implementation4(); + TransparentUpgradeableProxy proxy = new TransparentUpgradeableProxy( + address(instance4) + ); + Implementation2 instance2 = new Implementation2(); + proxy.upgradeTo(address(instance2)); + //use helper because proxy admin can't call getValue() + TestHelper h = new TestHelper(); + return h.getValue(address(proxy)); + } +} diff --git a/itests/contracts/compile.sh b/itests/contracts/compile.sh index 029bff46c..31bff4b68 100644 --- a/itests/contracts/compile.sh +++ b/itests/contracts/compile.sh @@ -5,7 +5,7 @@ set -o pipefail # to compile all of the .sol files to their corresponding evm binary files stored as .hex # solc outputs to stdout a format that we just want to grab the last line of and then remove the trailing newline on that line -find . -name \*.sol -print0 | +find . -maxdepth 1 -name \*.sol -print0 | xargs -0 -I{} bash -euc -o pipefail 'solc --bin {} |tail -n1 | tr -d "\n" > $(echo {} | sed -e s/.sol$/.hex/)' @@ -17,3 +17,7 @@ for filename in Constructor TestApp ValueSender Create2Factory DeployValueTest; solc --bin $filename.sol | tail -n5|head -n1 | tr -d "\n" > $filename.hex done +for filename in TransparentUpgradeableProxy ; do + echo $filename + solc --bin $filename.sol | tail -n1| tr -d "\n" > $filename.hex +done diff --git a/itests/eth_bytecode_test.go b/itests/eth_bytecode_test.go new file mode 100644 index 000000000..4d03a0f6d --- /dev/null +++ b/itests/eth_bytecode_test.go @@ -0,0 +1,74 @@ +package itests + +import ( + "context" + "encoding/hex" + "os" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/itests/kit" +) + +// TestGetCode ensures that GetCode returns the correct results for: +// 1. Placeholders. +// 2. Non-existent actors. +// 3. Normal EVM actors. +// 4. Self-destructed EVM actors. +func TestGetCode(t *testing.T) { + kit.QuietMiningLogs() + + blockTime := 100 * time.Millisecond + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC()) + ens.InterconnectAll().BeginMining(blockTime) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + // Accounts should have empty code. + { + // A random eth address should have no code. + _, ethAddr, filAddr := client.EVM().NewAccount() + bytecode, err := client.EVM().EthGetCode(ctx, ethAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + + // send some funds to the account. + kit.SendFunds(ctx, t, client, filAddr, types.FromFil(10)) + + // The code should still be empty, target is now a placeholder. + bytecode, err = client.EVM().EthGetCode(ctx, ethAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + } + + // Check contract code. + { + // install a contract + contractHex, err := os.ReadFile("./contracts/SelfDestruct.hex") + require.NoError(t, err) + contract, err := hex.DecodeString(string(contractHex)) + require.NoError(t, err) + createReturn := client.EVM().DeployContract(ctx, client.DefaultKey.Address, contract) + contractAddr := createReturn.EthAddress + contractFilAddr := *createReturn.RobustAddress + + // The newly deployed contract should not be empty. + bytecode, err := client.EVM().EthGetCode(ctx, contractAddr, "latest") + require.NoError(t, err) + require.NotEmpty(t, bytecode) + + // Destroy it. + _, _, err = client.EVM().InvokeContractByFuncName(ctx, client.DefaultKey.Address, contractFilAddr, "destroy()", nil) + require.NoError(t, err) + + // The code should be empty again. + bytecode, err = client.EVM().EthGetCode(ctx, contractAddr, "latest") + require.NoError(t, err) + require.Empty(t, bytecode) + } + +} diff --git a/itests/eth_fee_history_test.go b/itests/eth_fee_history_test.go index 9b256c527..72302f298 100644 --- a/itests/eth_fee_history_test.go +++ b/itests/eth_fee_history_test.go @@ -28,7 +28,7 @@ func TestEthFeeHistory(t *testing.T) { defer cancel() // Wait for the network to create 20 blocks - <-time.After(20 * blockTime) + client.WaitTillChain(ctx, kit.HeightAtLeast(20)) history, err := client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( json.Marshal([]interface{}{5, "0x10"}), @@ -37,6 +37,7 @@ func TestEthFeeHistory(t *testing.T) { require.Equal(6, len(history.BaseFeePerGas)) require.Equal(5, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + require.Nil(history.Reward) history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( json.Marshal([]interface{}{"5", "0x10"}), @@ -45,6 +46,7 @@ func TestEthFeeHistory(t *testing.T) { require.Equal(6, len(history.BaseFeePerGas)) require.Equal(5, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + require.Nil(history.Reward) history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( json.Marshal([]interface{}{"0x10", "0x12"}), @@ -53,6 +55,7 @@ func TestEthFeeHistory(t *testing.T) { require.Equal(17, len(history.BaseFeePerGas)) require.Equal(16, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(18-16+1), history.OldestBlock) + require.Nil(history.Reward) history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( json.Marshal([]interface{}{5, "0x10"}), @@ -61,6 +64,7 @@ func TestEthFeeHistory(t *testing.T) { require.Equal(6, len(history.BaseFeePerGas)) require.Equal(5, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(16-5+1), history.OldestBlock) + require.Nil(history.Reward) history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( json.Marshal([]interface{}{5, "10"}), @@ -69,19 +73,28 @@ func TestEthFeeHistory(t *testing.T) { require.Equal(6, len(history.BaseFeePerGas)) require.Equal(5, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock) + require.Nil(history.Reward) history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( - json.Marshal([]interface{}{5, "10", &[]float64{0.25, 0.50, 0.75}}), + json.Marshal([]interface{}{5, "10", &[]float64{25, 50, 75}}), ).Assert(require.NoError)) require.NoError(err) require.Equal(6, len(history.BaseFeePerGas)) require.Equal(5, len(history.GasUsedRatio)) require.Equal(ethtypes.EthUint64(10-5+1), history.OldestBlock) require.NotNil(history.Reward) - require.Equal(0, len(*history.Reward)) + require.Equal(5, len(*history.Reward)) + for _, arr := range *history.Reward { + require.Equal(3, len(arr)) + } history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( - json.Marshal([]interface{}{1025, "10", &[]float64{0.25, 0.50, 0.75}}), + json.Marshal([]interface{}{1025, "10", &[]float64{25, 50, 75}}), ).Assert(require.NoError)) require.Error(err) + + history, err = client.EthFeeHistory(ctx, result.Wrap[jsonrpc.RawParams]( + json.Marshal([]interface{}{5, "10", &[]float64{}}), + ).Assert(require.NoError)) + require.NoError(err) } diff --git a/itests/eth_filter_test.go b/itests/eth_filter_test.go index 9540c5ebe..1104bec13 100644 --- a/itests/eth_filter_test.go +++ b/itests/eth_filter_test.go @@ -136,6 +136,113 @@ func TestEthNewPendingTransactionFilter(t *testing.T) { } } +func TestEthNewPendingTransactionSub(t *testing.T) { + require := require.New(t) + + ctx, cancel := context.WithTimeout(context.Background(), time.Minute) + defer cancel() + + kit.QuietAllLogsExcept("events", "messagepool") + + client, _, ens := kit.EnsembleMinimal(t, kit.MockProofs(), kit.ThroughRPC(), kit.WithEthRPC()) + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + // create a new address where to send funds. + addr, err := client.WalletNew(ctx, types.KTBLS) + require.NoError(err) + + // get the existing balance from the default wallet to then split it. + bal, err := client.WalletBalance(ctx, client.DefaultKey.Address) + require.NoError(err) + + // install filter + subId, err := client.EthSubscribe(ctx, res.Wrap[jsonrpc.RawParams](json.Marshal(ethtypes.EthSubscribeParams{EventType: "newPendingTransactions"})).Assert(require.NoError)) + require.NoError(err) + + var subResponses []ethtypes.EthSubscriptionResponse + err = client.EthSubRouter.AddSub(ctx, subId, func(ctx context.Context, resp *ethtypes.EthSubscriptionResponse) error { + subResponses = append(subResponses, *resp) + return nil + }) + require.NoError(err) + + const iterations = 100 + + // we'll send half our balance (saving the other half for gas), + // in `iterations` increments. + toSend := big.Div(bal, big.NewInt(2)) + each := big.Div(toSend, big.NewInt(iterations)) + + waitAllCh := make(chan struct{}) + go func() { + headChangeCh, err := client.ChainNotify(ctx) + require.NoError(err) + <-headChangeCh // skip hccurrent + + defer func() { + close(waitAllCh) + }() + + count := 0 + for { + select { + case <-ctx.Done(): + return + case headChanges := <-headChangeCh: + for _, change := range headChanges { + if change.Type == store.HCApply { + msgs, err := client.ChainGetMessagesInTipset(ctx, change.Val.Key()) + require.NoError(err) + count += len(msgs) + if count == iterations { + return + } + } + } + } + } + }() + + var sms []*types.SignedMessage + for i := 0; i < iterations; i++ { + msg := &types.Message{ + From: client.DefaultKey.Address, + To: addr, + Value: each, + } + + sm, err := client.MpoolPushMessage(ctx, msg, nil) + require.NoError(err) + require.EqualValues(i, sm.Message.Nonce) + + sms = append(sms, sm) + } + + select { + case <-waitAllCh: + case <-ctx.Done(): + t.Errorf("timeout waiting to pack messages") + } + + expected := make(map[string]bool) + for _, sm := range sms { + hash, err := ethtypes.EthHashFromCid(sm.Cid()) + require.NoError(err) + expected[hash.String()] = false + } + + // expect to have seen iteration number of mpool messages + require.Equal(len(subResponses), len(expected), "expected number of filter results to equal number of messages") + + for _, txid := range subResponses { + expected[txid.Result.(string)] = true + } + + for _, found := range expected { + require.True(found) + } +} + func TestEthNewBlockFilter(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() diff --git a/itests/fevm_test.go b/itests/fevm_test.go index 2b2a3a6d3..3018bf63d 100644 --- a/itests/fevm_test.go +++ b/itests/fevm_test.go @@ -843,3 +843,28 @@ func TestFEVMBareTransferTriggersSmartContractLogic(t *testing.T) { // The receive() function emits one log, that's how we know we hit it. require.Len(t, receipt.Logs, 1) } + +func TestFEVMProxyUpgradeable(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //install transparently upgradeable proxy + proxyFilename := "contracts/TransparentUpgradeableProxy.hex" + fromAddr, contractAddr := client.EVM().DeployContractFromFilename(ctx, proxyFilename) + + _, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, contractAddr, "test()", []byte{}) + require.NoError(t, err) +} + +func TestFEVMGetBlockDifficulty(t *testing.T) { + ctx, cancel, client := kit.SetupFEVMTest(t) + defer cancel() + + //install contract + filenameActor := "contracts/GetDifficulty.hex" + fromAddr, contractAddr := client.EVM().DeployContractFromFilename(ctx, filenameActor) + + ret, _, err := client.EVM().InvokeContractByFuncName(ctx, fromAddr, contractAddr, "getDifficulty()", []byte{}) + require.NoError(t, err) + require.Equal(t, len(ret), 32) +} diff --git a/itests/kit/ensemble_opts_nv.go b/itests/kit/ensemble_opts_nv.go index c44dca92f..fa0d592bf 100644 --- a/itests/kit/ensemble_opts_nv.go +++ b/itests/kit/ensemble_opts_nv.go @@ -49,12 +49,12 @@ func LatestActorsAt(upgradeHeight abi.ChainEpoch) EnsembleOpt { }) /* inline-gen start */ return UpgradeSchedule(stmgr.Upgrade{ - Network: network.Version18, + Network: network.Version19, Height: -1, }, stmgr.Upgrade{ - Network: network.Version19, + Network: network.Version20, Height: upgradeHeight, - Migration: filcns.UpgradeActorsV11, + Migration: filcns.UpgradeActorsV12, }) /* inline-gen end */ } diff --git a/itests/kit/evm.go b/itests/kit/evm.go index 216a7f1f3..db8cf2cbb 100644 --- a/itests/kit/evm.go +++ b/itests/kit/evm.go @@ -19,7 +19,6 @@ import ( "golang.org/x/crypto/sha3" "github.com/filecoin-project/go-address" - amt4 "github.com/filecoin-project/go-amt-ipld/v4" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtintypes "github.com/filecoin-project/go-state-types/builtin" @@ -64,7 +63,7 @@ func (e *EVM) DeployContractWithValue(ctx context.Context, sender address.Addres require.NoError(err) e.t.Log("waiting for message to execute") - wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 0, 0, false) + wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 3, 0, false) require.NoError(err) require.True(wait.Receipt.ExitCode.IsSuccess(), "contract installation failed") @@ -128,7 +127,7 @@ func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target } e.t.Log("waiting for message to execute") - wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 0, 0, false) + wait, err := e.StateWaitMsg(ctx, smsg.Cid(), 3, 0, false) if err != nil { return nil, err } @@ -144,21 +143,10 @@ func (e *EVM) InvokeSolidity(ctx context.Context, sender address.Address, target func (e *EVM) LoadEvents(ctx context.Context, eventsRoot cid.Cid) []types.Event { require := require.New(e.t) - s := &apiIpldStore{ctx, e} - amt, err := amt4.LoadAMT(ctx, s, eventsRoot, amt4.UseTreeBitWidth(types.EventAMTBitwidth)) + events, err := e.ChainGetEvents(ctx, eventsRoot) require.NoError(err) - ret := make([]types.Event, 0, amt.Len()) - err = amt.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error { - var evt types.Event - if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil { - return err - } - ret = append(ret, evt) - return nil - }) - require.NoError(err) - return ret + return events } func (e *EVM) NewAccount() (*key.Key, ethtypes.EthAddress, address.Address) { diff --git a/itests/migration_nv20_test.go b/itests/migration_nv20_test.go new file mode 100644 index 000000000..c1c91d37c --- /dev/null +++ b/itests/migration_nv20_test.go @@ -0,0 +1,97 @@ +package itests + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/require" + + "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/manifest" + "github.com/filecoin-project/go-state-types/network" + gstStore "github.com/filecoin-project/go-state-types/store" + + "github.com/filecoin-project/lotus/blockstore" + "github.com/filecoin-project/lotus/chain/actors" + builtin2 "github.com/filecoin-project/lotus/chain/actors/builtin" + "github.com/filecoin-project/lotus/chain/consensus/filcns" + "github.com/filecoin-project/lotus/chain/state" + "github.com/filecoin-project/lotus/chain/stmgr" + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/lotus/chain/types/ethtypes" + "github.com/filecoin-project/lotus/chain/vm" + "github.com/filecoin-project/lotus/itests/kit" + "github.com/filecoin-project/lotus/node/impl" +) + +func TestMigrationNV20(t *testing.T) { + kit.QuietMiningLogs() + + upgradeEpoch := abi.ChainEpoch(100) + testClient, testMiner, ens := kit.EnsembleMinimal(t, kit.MockProofs(), + kit.UpgradeSchedule(stmgr.Upgrade{ + Network: network.Version19, + Height: -1, + }, stmgr.Upgrade{ + Network: network.Version20, + Height: upgradeEpoch, + Migration: filcns.UpgradeActorsV12, + }, + )) + + ens.InterconnectAll().BeginMining(10 * time.Millisecond) + + clientApi := testClient.FullNode.(*impl.FullNodeAPI) + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + testClient.WaitTillChain(ctx, kit.HeightAtLeast(upgradeEpoch+5)) + + bs := blockstore.NewAPIBlockstore(testClient) + ctxStore := gstStore.WrapBlockStore(ctx, bs) + + currTs, err := clientApi.ChainHead(ctx) + require.NoError(t, err) + + // Verify network version. + nv, err := testClient.StateNetworkVersion(ctx, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, network.Version20, nv) + + newStateTree, err := state.LoadStateTree(ctxStore, currTs.Blocks()[0].ParentStateRoot) + require.NoError(t, err) + + require.Equal(t, types.StateTreeVersion5, newStateTree.Version()) + + codeCids1, ok := actors.GetActorCodeIDsFromManifest(actorstypes.Version12) + require.True(t, ok) + + codeCids2, err := clientApi.StateActorCodeCIDs(ctx, nv) + require.NoError(t, err) + require.Equal(t, codeCids1, codeCids2) + + // Check that the miner actor was migrated. + minerActor, err := clientApi.StateGetActor(ctx, testMiner.ActorAddr, types.EmptyTSK) + require.NoError(t, err) + require.Equal(t, codeCids1[manifest.MinerKey], minerActor.Code) + + // check EAM + eamActor, err := newStateTree.GetActor(builtin.EthereumAddressManagerActorAddr) + require.NoError(t, err) + eamCodeCid, ok := codeCids1[manifest.EamKey] + require.True(t, ok) + require.Equal(t, eamCodeCid, eamActor.Code) + + // check the EthZeroAddress + ethZeroAddr, err := (ethtypes.EthAddress{}).ToFilecoinAddress() + require.NoError(t, err) + ethZeroAddrID, err := newStateTree.LookupID(ethZeroAddr) + require.NoError(t, err) + ethZeroActor, err := newStateTree.GetActor(ethZeroAddrID) + require.NoError(t, err) + require.True(t, builtin2.IsEthAccountActor(ethZeroActor.Code)) + require.Equal(t, vm.EmptyObjectCid, ethZeroActor.Head) +} diff --git a/itests/specs/eth_openrpc.json b/itests/specs/eth_openrpc.json index ed13614e9..1947bbd32 100644 --- a/itests/specs/eth_openrpc.json +++ b/itests/specs/eth_openrpc.json @@ -178,7 +178,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -253,8 +253,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -285,7 +285,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -354,8 +354,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -649,7 +649,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -724,8 +724,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -756,7 +756,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -825,8 +825,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3009,7 +3009,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3084,8 +3084,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3116,7 +3116,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3185,8 +3185,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3359,7 +3359,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3434,8 +3434,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3466,7 +3466,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3535,8 +3535,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3726,7 +3726,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3801,8 +3801,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." @@ -3833,7 +3833,7 @@ "s", "type", "value", - "yParity" + "v" ], "properties": { "type": { @@ -3902,8 +3902,8 @@ "pattern": "^0x([1-9a-f]+[0-9a-f]*|0)$", "description": "Chain ID that this transaction is valid on." }, - "yParity": { - "title": "yParity", + "v": { + "title": "v", "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." diff --git a/node/impl/full/chain.go b/node/impl/full/chain.go index 8448a542e..acbc056af 100644 --- a/node/impl/full/chain.go +++ b/node/impl/full/chain.go @@ -665,18 +665,41 @@ func (a *ChainAPI) ChainGetEvents(ctx context.Context, root cid.Cid) ([]types.Ev if err != nil { return nil, xerrors.Errorf("load events amt: %w", err) } + if evtArr.Len() == 0 { + return nil, nil + } + + // Hyperspace nv20: we peek into the events array to figure out if these + // are legacy events or not. + isLegacy, err := isLegacyEvents(ctx, evtArr) + if err != nil { + return nil, xerrors.Errorf("failed to determine if events AMT was legacy: %w", err) + } ret := make([]types.Event, 0, evtArr.Len()) - var evt types.Event err = evtArr.ForEach(ctx, func(u uint64, deferred *cbg.Deferred) error { if u > math.MaxInt { return xerrors.Errorf("too many events") } - if err := evt.UnmarshalCBOR(bytes.NewReader(deferred.Raw)); err != nil { - return err - } - ret = append(ret, evt) + r := bytes.NewReader(deferred.Raw) + if isLegacy { + var evt types.LegacyEvent + if err := evt.UnmarshalCBOR(r); err != nil { + return err + } + adapted, err := evt.Adapt() + if err != nil { + return err + } + ret = append(ret, adapted) + } else { + var evt types.Event + if err := evt.UnmarshalCBOR(r); err != nil { + return err + } + ret = append(ret, evt) + } return nil }) @@ -693,3 +716,44 @@ func (a *ChainAPI) ChainPrune(ctx context.Context, opts api.PruneOpts) error { return pruner.PruneChain(opts) } + +func isLegacyEvents(ctx context.Context, root *amt4.Root) (bool, error) { + var obj cbg.Deferred + if _, err := root.Get(ctx, 0, &obj); err != nil { + return false, xerrors.Errorf("failed to peek into events AMT: %w", err) + } + + r := cbg.NewCborReader(bytes.NewReader(obj.Raw)) + + // StampedEvent. + if typ, len, err := r.ReadHeader(); err != nil || typ != cbg.MajArray || len != 2 { + return false, xerrors.Errorf("expected cbor list with length 2 (stamped event); type: %d, size: %d, err: %s", typ, len, err) + } + + // ActorID + if typ, _, err := r.ReadHeader(); err != nil || typ != cbg.MajUnsignedInt { + return false, xerrors.Errorf("expected cbor unsigned int (actor id); err: %s", err) + } + + // Entries + if typ, len, err := r.ReadHeader(); err != nil || typ != cbg.MajArray { + return false, xerrors.Errorf("expected non-empty cbor list (entries); type: %d, size: %d, err: %s", typ, len, err) + } else if len == 0 { + // if we have no entries, it doesn't matter if we're new or legacy, so we'll assume we're new + return true, nil + } + + // First entry, finally + switch h, len, err := r.ReadHeader(); { + case err != nil: + return false, err + case h != cbg.MajArray: + return false, xerrors.Errorf("expected cbor major type %d when reading event; got: %d", cbg.MajArray, h) + case len == 3: + return true, nil + case len == 4: + return false, nil + default: + return false, xerrors.Errorf("unexpected event tuple length: %d", len) + } +} diff --git a/node/impl/full/eth.go b/node/impl/full/eth.go index 8401d7d51..772f7090b 100644 --- a/node/impl/full/eth.go +++ b/node/impl/full/eth.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "sort" "strconv" "sync" "time" @@ -25,6 +26,7 @@ import ( "github.com/filecoin-project/go-state-types/builtin/v10/evm" "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" @@ -426,22 +428,6 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, return nil, xerrors.Errorf("cannot get Filecoin address: %w", err) } - // use the system actor as the caller - from, err := address.NewIDAddress(0) - if err != nil { - return nil, fmt.Errorf("failed to construct system sender address: %w", err) - } - msg := &types.Message{ - From: from, - To: to, - Value: big.Zero(), - Method: builtintypes.MethodsEVM.GetBytecode, - Params: nil, - GasLimit: build.BlockGasLimit, - GasFeeCap: big.Zero(), - GasPremium: big.Zero(), - } - ts, err := a.parseBlkParam(ctx, blkParam) if err != nil { return nil, xerrors.Errorf("cannot parse block param: %s", blkParam) @@ -452,6 +438,31 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, return nil, xerrors.Errorf("block param must not specify genesis block") } + actor, err := a.StateManager.LoadActor(ctx, to, ts) + if err != nil { + if xerrors.Is(err, types.ErrActorNotFound) { + return nil, nil + } + return nil, xerrors.Errorf("failed to lookup contract %s: %w", ethAddr, err) + } + + // Not a contract. We could try to distinguish between accounts and "native" contracts here, + // but it's not worth it. + if !builtinactors.IsEvmActor(actor.Code) { + return nil, nil + } + + msg := &types.Message{ + From: builtinactors.SystemActorAddr, + To: to, + Value: big.Zero(), + Method: builtintypes.MethodsEVM.GetBytecode, + Params: nil, + GasLimit: build.BlockGasLimit, + GasFeeCap: big.Zero(), + GasPremium: big.Zero(), + } + // Try calling until we find a height with no migration. var res *api.InvocResult for { @@ -466,9 +477,7 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, } if err != nil { - // if the call resulted in error, this is not an EVM smart contract; - // return no bytecode. - return nil, nil + return nil, xerrors.Errorf("failed to call GetBytecode: %w", err) } if res.MsgRct == nil { @@ -476,15 +485,20 @@ func (a *EthModule) EthGetCode(ctx context.Context, ethAddr ethtypes.EthAddress, } if res.MsgRct.ExitCode.IsError() { - return nil, xerrors.Errorf("message execution failed: exit %s, reason: %s", res.MsgRct.ExitCode, res.Error) + return nil, xerrors.Errorf("GetBytecode failed: %s", res.Error) } - var bytecodeCid cbg.CborCid - if err := bytecodeCid.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return)); err != nil { + var getBytecodeReturn evm.GetBytecodeReturn + if err := getBytecodeReturn.UnmarshalCBOR(bytes.NewReader(res.MsgRct.Return)); err != nil { return nil, fmt.Errorf("failed to decode EVM bytecode CID: %w", err) } - blk, err := a.Chain.StateBlockstore().Get(ctx, cid.Cid(bytecodeCid)) + // The contract has selfdestructed, so the code is "empty". + if getBytecodeReturn.Cid == nil { + return nil, nil + } + + blk, err := a.Chain.StateBlockstore().Get(ctx, *getBytecodeReturn.Cid) if err != nil { return nil, fmt.Errorf("failed to get EVM bytecode: %w", err) } @@ -589,6 +603,18 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth if params.BlkCount > 1024 { return ethtypes.EthFeeHistory{}, fmt.Errorf("block count should be smaller than 1024") } + rewardPercentiles := make([]float64, 0) + if params.RewardPercentiles != nil { + rewardPercentiles = append(rewardPercentiles, *params.RewardPercentiles...) + } + for i, rp := range rewardPercentiles { + if rp < 0 || rp > 100 { + return ethtypes.EthFeeHistory{}, fmt.Errorf("invalid reward percentile: %f should be between 0 and 100", rp) + } + if i > 0 && rp < rewardPercentiles[i-1] { + return ethtypes.EthFeeHistory{}, fmt.Errorf("invalid reward percentile: %f should be larger than %f", rp, rewardPercentiles[i-1]) + } + } ts, err := a.parseBlkParam(ctx, params.NewestBlkNum) if err != nil { @@ -607,18 +633,40 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth // we can do is duplicate the last value. baseFeeArray := []ethtypes.EthBigInt{ethtypes.EthBigInt(ts.Blocks()[0].ParentBaseFee)} gasUsedRatioArray := []float64{} + rewardsArray := make([][]ethtypes.EthBigInt, 0) for ts.Height() >= abi.ChainEpoch(oldestBlkHeight) { // Unfortunately we need to rebuild the full message view so we can // totalize gas used in the tipset. - block, err := newEthBlockFromFilecoinTipSet(ctx, ts, false, a.Chain, a.StateAPI) + msgs, err := a.Chain.MessagesForTipset(ctx, ts) if err != nil { - return ethtypes.EthFeeHistory{}, fmt.Errorf("cannot create eth block: %v", err) + return ethtypes.EthFeeHistory{}, xerrors.Errorf("error loading messages for tipset: %v: %w", ts, err) } - // both arrays should be reversed at the end + txGasRewards := gasRewardSorter{} + for txIdx, msg := range msgs { + msgLookup, err := a.StateAPI.StateSearchMsg(ctx, types.EmptyTSK, msg.Cid(), api.LookbackNoLimit, false) + if err != nil || msgLookup == nil { + return ethtypes.EthFeeHistory{}, nil + } + + tx, err := newEthTxFromMessageLookup(ctx, msgLookup, txIdx, a.Chain, a.StateAPI) + if err != nil { + return ethtypes.EthFeeHistory{}, nil + } + + txGasRewards = append(txGasRewards, gasRewardTuple{ + reward: tx.Reward(ts.Blocks()[0].ParentBaseFee), + gas: uint64(msgLookup.Receipt.GasUsed), + }) + } + + rewards, totalGasUsed := calculateRewardsAndGasUsed(rewardPercentiles, txGasRewards) + + // arrays should be reversed at the end baseFeeArray = append(baseFeeArray, ethtypes.EthBigInt(ts.Blocks()[0].ParentBaseFee)) - gasUsedRatioArray = append(gasUsedRatioArray, float64(block.GasUsed)/float64(build.BlockGasLimit)) + gasUsedRatioArray = append(gasUsedRatioArray, float64(totalGasUsed)/float64(build.BlockGasLimit)) + rewardsArray = append(rewardsArray, rewards) parentTsKey := ts.Parents() ts, err = a.Chain.LoadTipSet(ctx, parentTsKey) @@ -634,6 +682,9 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth for i, j := 0, len(gasUsedRatioArray)-1; i < j; i, j = i+1, j-1 { gasUsedRatioArray[i], gasUsedRatioArray[j] = gasUsedRatioArray[j], gasUsedRatioArray[i] } + for i, j := 0, len(rewardsArray)-1; i < j; i, j = i+1, j-1 { + rewardsArray[i], rewardsArray[j] = rewardsArray[j], rewardsArray[i] + } ret := ethtypes.EthFeeHistory{ OldestBlock: ethtypes.EthUint64(oldestBlkHeight), @@ -641,13 +692,7 @@ func (a *EthModule) EthFeeHistory(ctx context.Context, p jsonrpc.RawParams) (eth GasUsedRatio: gasUsedRatioArray, } if params.RewardPercentiles != nil { - // TODO: Populate reward percentiles - // https://github.com/filecoin-project/lotus/issues/10236 - // We need to calculate the requested percentiles of effective gas premium - // based on the newest block (I presume it's the newest, we need to dig in - // as it's underspecified). Effective means we're clamped at the gas_fee_cap - base_fee. - reward := make([][]ethtypes.EthBigInt, 0) - ret.Reward = &reward + ret.Reward = &rewardsArray } return ret, nil } @@ -705,6 +750,13 @@ func (a *EthModule) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.Et return ethtypes.EmptyEthHash, err } + // Prior to nv20, delegated signature messages with no parameters carried MethodSend. + // Reset the value so the signature will roundtrip. + nv := a.StateManager.GetNetworkVersion(ctx, a.Chain.GetHeaviestTipSet().Height()) + if nv < network.Version20 && smsg.Message.Method == builtintypes.MethodsEVM.InvokeContract && len(smsg.Message.Params) == 0 { + smsg.Message.Method = builtintypes.MethodSend + } + _, err = a.MpoolAPI.MpoolPush(ctx, smsg) if err != nil { return ethtypes.EmptyEthHash, err @@ -739,18 +791,20 @@ func (a *EthModule) ethCallToFilecoinMessage(ctx context.Context, tx ethtypes.Et } var params []byte + if len(tx.Data) > 0 { + initcode := abi.CborBytes(tx.Data) + params2, err := actors.SerializeParams(&initcode) + if err != nil { + return nil, fmt.Errorf("failed to serialize params: %w", err) + } + params = params2 + } + var to address.Address var method abi.MethodNum if tx.To == nil { // this is a contract creation to = builtintypes.EthereumAddressManagerActorAddr - - initcode := abi.CborBytes(tx.Data) - params2, err := actors.SerializeParams(&initcode) - if err != nil { - return nil, fmt.Errorf("failed to serialize Create params: %w", err) - } - params = params2 method = builtintypes.MethodsEAM.CreateExternal } else { addr, err := tx.To.ToFilecoinAddress() @@ -758,16 +812,13 @@ func (a *EthModule) ethCallToFilecoinMessage(ctx context.Context, tx ethtypes.Et return nil, xerrors.Errorf("cannot get Filecoin address: %w", err) } to = addr - - if len(tx.Data) > 0 { - var buf bytes.Buffer - if err := cbg.WriteByteArray(&buf, tx.Data); err != nil { - return nil, fmt.Errorf("failed to encode tx input into a cbor byte-string") - } - params = buf.Bytes() - } - method = builtintypes.MethodsEVM.InvokeContract + + // < nv20 (Hyperspace): reset method to MethodSend if no params. + nv := a.StateManager.GetNetworkVersion(ctx, a.Chain.GetHeaviestTipSet().Height()) + if nv < network.Version20 && len(tx.Data) == 0 { + method = builtintypes.MethodSend + } } return &types.Message{ @@ -1234,8 +1285,9 @@ func (e *EthEvent) uninstallFilter(ctx context.Context, f filter.Filter) error { } const ( - EthSubscribeEventTypeHeads = "newHeads" - EthSubscribeEventTypeLogs = "logs" + EthSubscribeEventTypeHeads = "newHeads" + EthSubscribeEventTypeLogs = "logs" + EthSubscribeEventTypePendingTransactions = "newPendingTransactions" ) func (e *EthEvent) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethtypes.EthSubscriptionID, error) { @@ -1297,6 +1349,15 @@ func (e *EthEvent) EthSubscribe(ctx context.Context, p jsonrpc.RawParams) (ethty _, _ = e.EthUnsubscribe(ctx, sub.id) return ethtypes.EthSubscriptionID{}, err } + sub.addFilter(ctx, f) + case EthSubscribeEventTypePendingTransactions: + f, err := e.MemPoolFilterManager.Install(ctx) + if err != nil { + // clean up any previous filters added and stop the sub + _, _ = e.EthUnsubscribe(ctx, sub.id) + return ethtypes.EthSubscriptionID{}, err + } + sub.addFilter(ctx, f) default: return ethtypes.EthSubscriptionID{}, xerrors.Errorf("unsupported event type: %s", params.EventType) @@ -1617,6 +1678,15 @@ func (e *ethSubscription) start(ctx context.Context) { } e.send(ctx, ev) + case *types.SignedMessage: // mpool txid + evs, err := ethFilterResultFromMessages([]*types.SignedMessage{vt}, e.StateAPI) + if err != nil { + continue + } + + for _, r := range evs.Results { + e.send(ctx, r) + } default: log.Warnf("unexpected subscription value type: %T", vt) } @@ -2123,3 +2193,50 @@ func parseEthTopics(topics ethtypes.EthTopicSpec) (map[string][][]byte, error) { } return keys, nil } + +func calculateRewardsAndGasUsed(rewardPercentiles []float64, txGasRewards gasRewardSorter) ([]ethtypes.EthBigInt, uint64) { + var totalGasUsed uint64 + for _, tx := range txGasRewards { + totalGasUsed += tx.gas + } + + rewards := make([]ethtypes.EthBigInt, len(rewardPercentiles)) + for i := range rewards { + rewards[i] = ethtypes.EthBigIntZero + } + + if len(txGasRewards) == 0 { + return rewards, totalGasUsed + } + + sort.Stable(txGasRewards) + + var idx int + var sum uint64 + for i, percentile := range rewardPercentiles { + threshold := uint64(float64(totalGasUsed) * percentile / 100) + for sum < threshold && idx < len(txGasRewards)-1 { + sum += txGasRewards[idx].gas + idx++ + } + rewards[i] = txGasRewards[idx].reward + } + + return rewards, totalGasUsed +} + +type gasRewardTuple struct { + gas uint64 + reward ethtypes.EthBigInt +} + +// sorted in ascending order +type gasRewardSorter []gasRewardTuple + +func (g gasRewardSorter) Len() int { return len(g) } +func (g gasRewardSorter) Swap(i, j int) { + g[i], g[j] = g[j], g[i] +} +func (g gasRewardSorter) Less(i, j int) bool { + return g[i].reward.Int.Cmp(g[j].reward.Int) == -1 +} diff --git a/node/impl/full/eth_test.go b/node/impl/full/eth_test.go index 027becf34..67a8b0500 100644 --- a/node/impl/full/eth_test.go +++ b/node/impl/full/eth_test.go @@ -6,6 +6,8 @@ import ( "github.com/ipfs/go-cid" "github.com/stretchr/testify/require" + "github.com/filecoin-project/go-state-types/big" + "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/chain/types/ethtypes" ) @@ -100,3 +102,65 @@ func TestEthLogFromEvent(t *testing.T) { require.Len(t, topics, 1) require.Equal(t, topics[0], ethtypes.EthHash{}) } + +func TestReward(t *testing.T) { + baseFee := big.NewInt(100) + testcases := []struct { + maxFeePerGas, maxPriorityFeePerGas big.Int + answer big.Int + }{ + {maxFeePerGas: big.NewInt(600), maxPriorityFeePerGas: big.NewInt(200), answer: big.NewInt(200)}, + {maxFeePerGas: big.NewInt(600), maxPriorityFeePerGas: big.NewInt(300), answer: big.NewInt(300)}, + {maxFeePerGas: big.NewInt(600), maxPriorityFeePerGas: big.NewInt(500), answer: big.NewInt(500)}, + {maxFeePerGas: big.NewInt(600), maxPriorityFeePerGas: big.NewInt(600), answer: big.NewInt(500)}, + {maxFeePerGas: big.NewInt(600), maxPriorityFeePerGas: big.NewInt(1000), answer: big.NewInt(500)}, + {maxFeePerGas: big.NewInt(50), maxPriorityFeePerGas: big.NewInt(200), answer: big.NewInt(-50)}, + } + for _, tc := range testcases { + tx := ethtypes.EthTx{ + MaxFeePerGas: ethtypes.EthBigInt(tc.maxFeePerGas), + MaxPriorityFeePerGas: ethtypes.EthBigInt(tc.maxPriorityFeePerGas), + } + reward := tx.Reward(baseFee) + require.Equal(t, 0, reward.Int.Cmp(tc.answer.Int), reward, tc.answer) + } +} + +func TestRewardPercentiles(t *testing.T) { + testcases := []struct { + percentiles []float64 + txGasRewards gasRewardSorter + answer []int64 + }{ + { + percentiles: []float64{25, 50, 75}, + txGasRewards: []gasRewardTuple{}, + answer: []int64{0, 0, 0}, + }, + { + percentiles: []float64{25, 50, 75, 100}, + txGasRewards: []gasRewardTuple{ + {gas: uint64(0), reward: ethtypes.EthBigInt(big.NewInt(300))}, + {gas: uint64(100), reward: ethtypes.EthBigInt(big.NewInt(200))}, + {gas: uint64(350), reward: ethtypes.EthBigInt(big.NewInt(100))}, + {gas: uint64(500), reward: ethtypes.EthBigInt(big.NewInt(600))}, + {gas: uint64(300), reward: ethtypes.EthBigInt(big.NewInt(700))}, + }, + answer: []int64{200, 700, 700, 700}, + }, + } + for _, tc := range testcases { + rewards, totalGasUsed := calculateRewardsAndGasUsed(tc.percentiles, tc.txGasRewards) + gasUsed := uint64(0) + for _, tx := range tc.txGasRewards { + gasUsed += tx.gas + } + ans := []ethtypes.EthBigInt{} + for _, bi := range tc.answer { + ans = append(ans, ethtypes.EthBigInt(big.NewInt(bi))) + } + require.Equal(t, totalGasUsed, gasUsed) + require.Equal(t, len(ans), len(tc.percentiles)) + require.Equal(t, ans, rewards) + } +} diff --git a/node/modules/actorevent.go b/node/modules/actorevent.go index 55a79a59a..a40d208aa 100644 --- a/node/modules/actorevent.go +++ b/node/modules/actorevent.go @@ -92,8 +92,9 @@ func EthEventAPI(cfg config.FevmConfig) func(helpers.MetricsCtx, repo.LockedRepo } ee.EventFilterManager = &filter.EventFilterManager{ - ChainStore: cs, - EventIndex: eventIndex, // will be nil unless EnableHistoricFilterAPI is true + ChainStore: cs, + EventGetter: chainapi.ChainGetEvents, + EventIndex: eventIndex, // will be nil unless EnableHistoricFilterAPI is true AddressResolver: func(ctx context.Context, emitter abi.ActorID, ts *types.TipSet) (address.Address, bool) { // we only want to match using f4 addresses idAddr, err := address.NewIDAddress(uint64(emitter))