diff --git a/.github/workflows/parachain.yml b/.github/workflows/parachain.yml index badd13599..0226cdc4b 100644 --- a/.github/workflows/parachain.yml +++ b/.github/workflows/parachain.yml @@ -100,10 +100,6 @@ jobs: args: >- --manifest-path parachain/Cargo.toml --verbose --workspace - --exclude snowbridge - --exclude snowbridge-runtime - --exclude snowblink-runtime - --exclude snowbase-runtime --features runtime-benchmarks --avoid-cfg-tarpaulin --coveralls ${{ secrets.COVERALLS_REPO_TOKEN }} diff --git a/cumulus b/cumulus index 7ca7ba411..9fdbaf6bd 160000 --- a/cumulus +++ b/cumulus @@ -1 +1 @@ -Subproject commit 7ca7ba411f2b90c0ab74178496fad330834e6cd1 +Subproject commit 9fdbaf6bd4e77f48cca6a3c33a2c52d6db6b7d69 diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index e9777ce15..e6340b85d 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -3494,9 +3494,11 @@ checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" name = "snowbridge-beacon-primitives" version = "0.0.1" dependencies = [ + "byte-slice-cast", "frame-support", "frame-system", "hex", + "hex-literal", "parity-scale-codec", "rlp", "scale-info", @@ -3506,6 +3508,9 @@ dependencies = [ "sp-io 7.0.0", "sp-runtime 7.0.0", "sp-std 5.0.0", + "ssz-rs", + "ssz-rs-derive", + "static_assertions", ] [[package]] @@ -3576,6 +3581,7 @@ dependencies = [ "sp-std 5.0.0", "ssz-rs", "ssz-rs-derive", + "static_assertions", ] [[package]] diff --git a/parachain/pallets/ethereum-beacon-client/Cargo.toml b/parachain/pallets/ethereum-beacon-client/Cargo.toml index 1f232a5d7..5e9bd0c65 100644 --- a/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/parachain/pallets/ethereum-beacon-client/Cargo.toml @@ -26,15 +26,16 @@ frame-support = { git = "https://github.com/paritytech/substrate.git", branch = frame-system = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } -sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } -snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false } +primitives = { package = "snowbridge-beacon-primitives", path = "../../primitives/beacon", default-features = false } +static_assertions = { version = "1.1.0" } [dev-dependencies] sp-keyring = { git = "https://github.com/paritytech/substrate.git", branch = "master" } +sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "master" } snowbridge-testutils = { path = "../../primitives/testutils" } serde_json = "1.0.96" hex-literal = { version = "0.4.1" } @@ -50,12 +51,11 @@ std = [ "frame-system/std", 'frame-benchmarking/std', "sp-core/std", - "sp-io/std", "sp-runtime/std", "sp-std/std", "snowbridge-core/std", "snowbridge-ethereum/std", - "snowbridge-beacon-primitives/std", + "primitives/std", "milagro_bls/std", "ssz-rs/std", "byte-slice-cast/std", diff --git a/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_mainnet.rs b/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_mainnet.rs index 0aa831776..5a8d3f14e 100644 --- a/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_mainnet.rs +++ b/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_mainnet.rs @@ -1,19 +1,16 @@ // Generated, do not edit! // See README.md for instructions to generate -use frame_support::traits::Get; use hex_literal::hex; -use snowbridge_beacon_primitives::{ - BeaconHeader, ExecutionPayloadHeader, FinalizedHeaderUpdate, HeaderUpdate, InitialSync, - PublicKey, SyncAggregate, SyncCommittee, SyncCommitteePeriodUpdate, -}; +use primitives::{BeaconHeader, ExecutionPayloadHeader, SyncAggregate, SyncCommittee}; use sp_core::U256; use sp_std::vec; -pub fn initial_sync, ProofSize: Get>( -) -> InitialSync { +use crate::{FinalizedHeaderUpdate, HeaderUpdate, InitialUpdate, SyncCommitteeUpdate}; + +pub fn initial_sync() -> InitialUpdate { let time_now = 1675679352; //2023.2.6 - return InitialSync{ + return InitialUpdate{ header: BeaconHeader{ slot: 5218016, proposer_index: 126987, @@ -22,521 +19,521 @@ pub fn initial_sync, ProofSize: Get>( body_root: hex!("ed25087a8ee76d652792a1a40bf54c3741f97f6cbf49361387f90c5f091a630c").into(), }, current_sync_committee: SyncCommittee{ - pubkeys: vec![ - PublicKey(hex!("a7e8e3ac727b352f35c6d775177b7abf6e8c417ea64d48843fa20a97dc6b4a2ab13534e1ea7e82f4673ab9ac5e1867c8").into()), - PublicKey(hex!("8fe2698be132a121a53d3ccbec44cf128693ae779d24b198b51c02c2992927ebbfdd29e3fc950d8a06bb239f5fa6a342").into()), - PublicKey(hex!("b340701986d59d4ff5dc0e2c725c7cbf1fcc78882f057d5524b41ea881ce5d63bc6b67a99efb1f76e6cb64af37e20ced").into()), - PublicKey(hex!("a11a9607daf5ce4e7eff377b926bc44f8edc4d15da0d0b0784f2e50fba5fa3d3c947e5b8911df60669b5ece7b0d22496").into()), - PublicKey(hex!("8d980517aeea95faab9ba54e154165ca1cad568016f420fb97a1dc80b95260dd33e86c480bbd4613a6b45d27794bb78e").into()), - PublicKey(hex!("894042990af1fb6a6b8ee3c674f0ef656153dd1ca214f6ed2245ebbbf269968ef283560c8f0d082301c2edb595362faa").into()), - PublicKey(hex!("8f66251d2efa3f5b161f63ad9471a43bb3162150283e304acd2a9c38df1c2865e3c2d52ab42fb0e30fa17c568914b1f8").into()), - PublicKey(hex!("84470a956fde4ce248bc9e7fcc8fcf0d3293f8c67919cd0f2cec99c117d659735cf4164cf9e89051a63c9b4198bd4bb2").into()), - PublicKey(hex!("b7fe047325a99316990857234f641416faf30e72b9ac53e5d5c3dbded0e244b21f8bc2a97173a2f8f7f7c7b4095f4531").into()), - PublicKey(hex!("afc0993213b1e5cb0cee79b059c63613c4c5f8ce590991201bc186d818e08731c193de70dba35572a2aec90d6cc83ef5").into()), - PublicKey(hex!("957b21902f391a27adac9708d6809a6befd7ca12796dc6783869f3f34e8a24d6b60c4e58b858ffa330325e66f40d933f").into()), - PublicKey(hex!("8fde4607d06a75115f5fd62e55cac0c77b29ca6d7181123ea28279c0345f5e6c7273df12a324157d69e0889cd0d75456").into()), - PublicKey(hex!("8abad528201ba6c444bacc7a3e8120d528cd25ca084cbd881d179b70e01ce703d58db313164c01b1c5a0711a93a7cbe6").into()), - PublicKey(hex!("a5edacf72d6f69cc637cb96815a66bbc61d7dd67e2a3787a23065d9ce7d42664664ae24ef0817c30b33ee626043046d4").into()), - PublicKey(hex!("84c3b7bc6d0da4fac4110346600436eb63871676da86710ac4eb0cb2172895a1d4d4a3db38b6f4cbf3c8a1b0825d3490").into()), - PublicKey(hex!("b7d570ff2be844df4bb566e6b5657cf55e50909316e4c1f688a63347433fd663196c441b7a454722f47ab48d4beee31e").into()), - PublicKey(hex!("b5fde0910e6c4030681a060f60bb065fd004a124b7ae0320f88cc7ad247c324d7bb6be25ae8a0b8fd48f00a82e82d142").into()), - PublicKey(hex!("85af33928106db4602d10479f2344d44bd9048a051d0aa71cb375314523cde681ad7229bac063cb5216ea88570ad817a").into()), - PublicKey(hex!("afd11906038ab5068257dad993579495080f9c242f0ae4a023673717e6afc16872372e708383ccc5f3377b0494c48bb1").into()), - PublicKey(hex!("8ac30146cce791a328f362ba9d03aba246875f14468b709e63ab3139c9ae7694a29694bb248bf0ecd781c8d21ac50eb1").into()), - PublicKey(hex!("a021597d204e479496b4aabfc38453e8d8952e8a79a1e843da06c720611248a722c03ef7d02f34d84b4d95a148fd74e9").into()), - PublicKey(hex!("b60da87146297451c80d8eb9924469599c1f4338a58dbb7d46adb9226bacd5e7dbe9b153b62315c82e332dcdac16f75c").into()), - PublicKey(hex!("a96aa204b681dc2c005567759c1b9c1f8d3b6baa9e2b4ec9020a5ed689b1025b591651a6a688669ad31827f8c9c39988").into()), - PublicKey(hex!("8768e956ba3d684e6ea42629d73f6494cf615e4e3b02ef7b521cc28e373bbc895144b0f764ae676244a7d79c7d5eaaf5").into()), - PublicKey(hex!("b9e2c729c583a6341b6a0f5f13db577fa49e2b48a0b07319e630596f62b90a433aabeccff9c257c6de103f8cbb0cf539").into()), - PublicKey(hex!("829900dabac47024f9407bdf342c61c8d791e0d44a79b485ece54e236cc6787e2e43629509e1603dc1b6cc154c584b3b").into()), - PublicKey(hex!("a9d09e1844e25892a9810db0f20d99932609849f3d24fce2834f2ede77f60d2a2c7267e23f2cbfae7677ebf34bd37826").into()), - PublicKey(hex!("b4c9bf28d74f4ce903a5397fa272d09c0085b5adbb3ca56d73189939c6484f1bc945d6840aebea8769bc5e45b0b1e3b3").into()), - PublicKey(hex!("a97c7a6f84ba137a5343ff6ba33a78eaf151e8f52c700efabb34d5c3d646aab4e35f789de20feacb5321531a87065fe4").into()), - PublicKey(hex!("a80cb7843f0dfe5b69c209aa8422d314c489d4ed3603f19588e1d1b7fefa77b934f4f6be163577dd7d9e30888eb9f1f1").into()), - PublicKey(hex!("a2a6ba8b60c11b94904fab110509ecbb806fc2e693683b15ea65948f18495799fd88ee085d07edeaaeb5f521e539eee8").into()), - PublicKey(hex!("97e27e88808f725a23aeb435904ffacc74fac92dcfe1dad8b4a9b70133f02d7102b7287574437f88eb2082dc9599818d").into()), - PublicKey(hex!("96250f94999f7ab3e20f639263ae780432ec04d54d48880c2bc7ab1cbd8fc6803bbf5907f8b7117d80e3aea4137150d0").into()), - PublicKey(hex!("942e02d4bf5864ee00401a1e60af8ba79ae675fea95fab314aa676e50b37dd75ad890fa0766e3362ac3bf19fa725af9a").into()), - PublicKey(hex!("b6b8b28d96c50d456a28cae6fe2b69e28507ff9a55d40ef799f79d4951fdac36103a47d36f7c5a0237f274fb66661e52").into()), - PublicKey(hex!("82ff5885b86fc1a78cfa90ac4da8c03763c88d0e9312b4f776b58d3461416e60d0b5d7fca091d3d2e90f3305a06de3de").into()), - PublicKey(hex!("a513d01ac867507fd060b5622a525b7836c09371e9ca25504b7751a7ffb5e51c846ed0976cb850eb68ba250fe0555bf0").into()), - PublicKey(hex!("b02a46760b6e4f4964d14cbe1ae6ebf46e23a9b6d30e86e0faa280aac9ae0ea2da2dea0b1a87a371758831ab82d6c2e8").into()), - PublicKey(hex!("817f3e3e83957e93dec44e9c1f12b532d1536849c0751622a220a27e0acde4e66cd4691fbb5e3c4fff061a90f9d93ee9").into()), - PublicKey(hex!("a984a592980bac71652bc1f4b48580ce9e93641de7c29dcb65d63dc095ad5fb28e2b5cd866f7f48658d5f62bfb693987").into()), - PublicKey(hex!("b2de2174c65e730b24103d1fba5738a826256937657591a6fbbed552fe6e8e8d6c7ef636007fc810aefd3b2817b5ad67").into()), - PublicKey(hex!("a517a67fbd27691c660f6af1a4b661e85dad8b4e88988da2e22eccd63829092f4b4d8c347161198c7b39605b0339c05c").into()), - PublicKey(hex!("a02147bdc65f13c5dee80f213b0922fda7ff91a1e3356de48861339b91a379284d02732735adb024fff4498a77ab5fb7").into()), - PublicKey(hex!("a7b71f8a4535e574c953e33282b12cad6af772ad0460542c0a6f9baf7fcaffa58f46eb9bb7fc20e8b83a175e80a9fc0a").into()), - PublicKey(hex!("b462c598ef2093f5eb88ed8860c60aae2e8056197e2c6bee34ecd3e2c89a96421280b3d7ae1d273244ac933c53640cf8").into()), - PublicKey(hex!("b4c717c77f5824de012d69e921504cb3c75a21b98cbeef97f8b38187c1bd8f24ac54da29c759b32b97e391dd9b76e2fe").into()), - PublicKey(hex!("8bdc42503f8ff93da336d9c950487324985e91085613594488481854728b02b03d448e2316f9f0310c880131d9522718").into()), - PublicKey(hex!("90ff3872939fbae7b6221ebcf0e481533109549ff169483c1590fc65f617677b10ab01329cbbf4a091f7930d47b37d8d").into()), - PublicKey(hex!("af2766fe19f07af307a42dff6484de260e51f1f76908793332ac0258917c969dbf605ecbd39f4b41cbf37f747566992b").into()), - PublicKey(hex!("a9b1ce53f971637f6d3c9b0432400b2fb7b57d56538429f171e8a82164b6dcfb3e085f943d5c59f5b49896bf1e03c687").into()), - PublicKey(hex!("b064577d2c8bbc90d57d501dfeafd4ff609d371fe3b9156a30a21016d980e46d1017151cce8750e7ba90dc4628ed5efa").into()), - PublicKey(hex!("829b55e6840a230ac2acc728e9414118aa2f891b3512d6569e0f18e1762f9e1ca974c6a2f7c01bbce15add80ad5c53c9").into()), - PublicKey(hex!("b73597c5ffd3a812e8a553bd3ad2216282fe7c1203120624b86cacb8a7421ea6807e29fac3383cfd61d632db8e3af5d8").into()), - PublicKey(hex!("8a8b0cbebe482dc32e56ef65fa06bb7380639430982b33d1d63b6b0958fe38b40f3a9cadbf304cf635ee1ef5adcd0f10").into()), - PublicKey(hex!("a846dd941e176bdadb6e8c32ef23e6150a8ef77afebbf8176a2730f3558e709d1f04a991ebcbe7618b7ce209211a095b").into()), - PublicKey(hex!("a31007b732db94c9b8795c84e1a553c4cd4eadf6d11b445118e07f0fe87a2705557187cda0f4830cc4134b608baa6d8f").into()), - PublicKey(hex!("b4caab40168017630c8aa2b8ceebbf3ac75017524279dc7b637ebde8ea746362480ae15525730a46a164a664843c1131").into()), - PublicKey(hex!("a87241999940c8fb64632574abaa4669e1f78206f5fcac763c8eb4f0a08fc4b4eb8804a772440dd9d38949d4d14bff25").into()), - PublicKey(hex!("ab529992bb29bb00aba71d378d12e2e501bce1d1a2e3040966db463cd8a996f2dd35b578bbdf709c8603211b4b3425cf").into()), - PublicKey(hex!("9631260b7cc849335140e53bbb30220eb8750990a3185a1eafcddf39baab9eb51d3cb807566e0057aca803e931c76153").into()), - PublicKey(hex!("8825e541b5389241bf80565c3818f62c1eff16b3bafbf0cfc77e108c5ec8409279a90da283c2c6288d4db1e2d3afb54a").into()), - PublicKey(hex!("91a416b713ed83dd4d7fb0fc0c202356c38fdc796dc757ef5dbecc01b88254cb3eb82395ca94c93da1cffcc394873237").into()), - PublicKey(hex!("80e79d3c1c3d04ed8ec23625d82c91d9d0b7cf2c847c7705958a671d683e698d03d7041bb2f67ac3c412faf82e885fba").into()), - PublicKey(hex!("8f7f00013e39e1db69780e3d2ac6442847d9ba6316ec6e9890233543d5e9e5e9e13d6de01f1a8f02550932f613bdeac2").into()), - PublicKey(hex!("94f378a935ba5e39ddd0a5e53ac93a4872e5c2ecd6de37b48d601d9232c76d9a3352381efe611a8465b8862f58afdc6d").into()), - PublicKey(hex!("8c8bcdaf1d9199e54ce64c01d594def4247d318cfaa25e03f10583da35dbf965f8583ed090dd417d1d5e90c828843a8e").into()), - PublicKey(hex!("b2bb5dcdc58b045c28cfb9a432896a4faa845893202d2e0411a237913874d23f3232e8e2abf8df636614a0e4f8a23796").into()), - PublicKey(hex!("9068cea93749dc004003daca8d814364e08ff9c2121abf1e04c233051d272410f0bc177e21032ac8a2181362f3eaf87d").into()), - PublicKey(hex!("947e4a8629d714492752214f26da22b7c9a45cf0535643c7b85d288749baba19832ba6049a2a1c4031bf382b56429768").into()), - PublicKey(hex!("975efbfb4e34b91a191f00a51dcc2817de8c679543fc0699d4043b6fb32c959d62aa69755d1399f5a4e037cc0feb137d").into()), - PublicKey(hex!("8d8ad83645448f8e63e26ec76c9dbebe01bfa11d8abbbccdcbc9abf32f833dd32ac14d4cc93a84aa70c9085ee09c768b").into()), - PublicKey(hex!("89803b8dbf715f1d5c643962c1d19a3002cb7bb64d0f489070fc0df0097845591c0d07d7460715089cb32221d022a710").into()), - PublicKey(hex!("b94ef3f9253020ce53fcb7a7b466e03504c517c33cc914e3dfe4353685e7e0eb7f45962e1efec5d3b04e4efddd4356c2").into()), - PublicKey(hex!("96ccfb2bde1c8055e4e73ed2fd6f6830343ac16f0c44b8b6702a20a0a9ddb36766c699a1bee4b6227132c1361eb685e7").into()), - PublicKey(hex!("aacb3053d9172a9cae8682d6c443b04dc0dc1e61c093f6a1d2aa4bc42e91d223366550b04a4f72d7592b7e5df9312363").into()), - PublicKey(hex!("b720f4a832f5c5c3690b47f2925f3bde24cf11feba30657f2d7f7f04bb910fcff4e4269a611a182f645d7293225566da").into()), - PublicKey(hex!("a3b71e15bdb3cffb1c3c293396461dbf3e47e2f0503812e8016a23a73932e84377e5520b9978521daa02ea1db220beec").into()), - PublicKey(hex!("a23adbd995983488814b1ea9422bbf8c5985eaf6a3c2a5f136bb9f51c7e11ab6879e15b462b49a462336fe4424b7711e").into()), - PublicKey(hex!("abc88c9c9b04ecb517a22cf2435a8a1316e01213295bc028a660c98f256ae2af58674bb99aa368cb074da7cff9e7a712").into()), - PublicKey(hex!("825893a3994804fe91c2db7829783f48bd7251be4570401e983ee33f3dacdf5e4b9fd65784e59276cd22fa6433863680").into()), - PublicKey(hex!("89ebd0ac9cfb3d891c6be18151843c52c41361f131a90fc569547e014aa1fd3e3c6d692156a085ce8023714cec9d6f46").into()), - PublicKey(hex!("9843669e01aac59485029d7cd1eb6e8a06aaa7464c5832e0e593b9e4d25da88bdae3b3d0994a84414586e3d21004e1b0").into()), - PublicKey(hex!("8cf955a0ef51424f14c7305f3fb342c18d025e52a3ffa06076147ac35f735a5711733843c32aad4321896e2633a76fdd").into()), - PublicKey(hex!("921a2900b2e63f25a35afe19c1e2cde8f2e4a7e81346eeef6c209dfd16ff4ae4c1bab98bc1a0b9598712d9c884a62a18").into()), - PublicKey(hex!("b9d514458e9c8c8c7b365ab64fe9b1adbd5d7ab6dea2dc2c944907fa3eb69b0cf0b04443ca718b7e6ed25b39a306fa0f").into()), - PublicKey(hex!("b334310c8c6061b5efa96e10bfd1014e907626bea02bf191afaf830bd1c9a4793c7517cac9b13fd79f6f9bb2510996cf").into()), - PublicKey(hex!("ae7f4a17e2209ec3be9f25349cdc0d6c0caef53def09e897a6ae424f7c2b74aab14738c2f9c0a2f1f2cfc83c61dbfcaa").into()), - PublicKey(hex!("b0ef0d9260c0e0b6068865afc3c70457ef34237ae82d1f57c72fa1a40c9b68580aef667e122c28e1aa6ecbf799f37c71").into()), - PublicKey(hex!("861d6ede329c29c8fe9d1cef8c9a9abfd5f1aa4e2504fe5e2c30e419ff857ee7493d4bae5f9a77d23b8309dd44570a81").into()), - PublicKey(hex!("b59856606d64ad072a16f8ba4765ceffe08d9abde687eed80eeaf3a0b17bbd472981ddaf6bc449de7917a951a47c8149").into()), - PublicKey(hex!("a19ef1c85919c6e9851207be28009ef5851adeee438d1652145b6bbd1bbdbb016f86f213a30f6afab8623fd95dba7282").into()), - PublicKey(hex!("a585a2ce2bc6bd0c0cc3cbcad36d76e73ef88892268c5e7c3edc92ba92ae96fd2075f5720064ef5ee750bd2c07beafea").into()), - PublicKey(hex!("94989b6f2d521cec8b633abd69ba60372370469740ba9cdd017a2892be122466ec46f17998438813e9b0aaf3054250c1").into()), - PublicKey(hex!("8d5293a363665f304bfa3e1ac13984b804cbab432cbd6255e19f9aaf2484aee5f233ce94339b09189bc4a48035767886").into()), - PublicKey(hex!("83e81be1e8dae75e8b6e6169d45478208ba4bcf109cf6ec9651ef018e0816f4dc265af02fab4f47cb1f08535b6a905e4").into()), - PublicKey(hex!("b1f261d67d5602b6542d9e9601494fde0c5f0516e64b6dd580fa55c7253834a41190902c700f1c261af3100c230a814a").into()), - PublicKey(hex!("81126dcccce988efed837cc09a5f231aaee3252fdbc2da28382bf670248db9a8c31767dcb9188ed1a7e5ac001a59901d").into()), - PublicKey(hex!("b42b78fc278c0ab6c5ddf41e935141a8e21bdc97ca6ed3171fd013818381bf86983411392d40b6ddf7ce9f4a35a46edc").into()), - PublicKey(hex!("8081ed92a2bdc7659b23cd03a4e4e78ab208ac5b6bbcbf6ae457c3c8e38d8cb66b6882fa1555e9adfd5c44beb4168870").into()), - PublicKey(hex!("8e6df9aebbafc5af5e94ad47a0954eaddaff7055f3c4f9f10c68d34fa6b5a6a63a59408f203a6fb447a721f4bd84bace").into()), - PublicKey(hex!("87defe0569358da36a2d15b72761bfa8cdd6531be38a63c1e5efa61c03e447664121b6fe4b6b1854924bad66acfea735").into()), - PublicKey(hex!("87d3bc2590864ded7749603ece2a9ac81f114d05a3f3af5a102c7aefd08509d8342699c25f309301244e627ae7164a20").into()), - PublicKey(hex!("a4e4a77c5c3cc5588a8e17594c72b1237bf0926f6b0a00369cc859020ac940fc658d0f6f81d73c5bcb6962504e3798a7").into()), - PublicKey(hex!("acbe8ee3cbd1dbd3d097cd6c0f4e905ba805adef813ba9ebc5cc50c82cb96a9ac40161e8f401d20778df9bd825e74d9a").into()), - PublicKey(hex!("863bdb7fd7388ca56688f9dd5695b388032bfd71f129771955150e191faba18063074db3584a3a9ef6631254b7066324").into()), - PublicKey(hex!("a65aa678985bdde297be4f94ff710004ab2df647122586ae63a79ef2f07e3e2ecd8c2f8b2172a32cf1c3676d61854577").into()), - PublicKey(hex!("90b69711231c5e7be90ce066ed325121fecdba493f7a190f16ef4430b6374906917de4a903440b0012ba59ef127840ee").into()), - PublicKey(hex!("b107e95dafde20f4aacb66ba468da816489ad4ab3d2071067245f42734e357ecc815ce053645ea7205053c66b509d5f7").into()), - PublicKey(hex!("b68f16ded8e64ff88295d183c1da09f3a089c52dd3fa8731a576971eadf04fadaeba4e4f4995e5f1d24b88ad42e804cd").into()), - PublicKey(hex!("b2ec93bc192526ea6f35150c76060fee0689f2e3c9d07338f96215c5ee104d12891556b8001ef0b088967bf014c068cd").into()), - PublicKey(hex!("a84316ce6764e6f9a66b57b28664919ee48636e40df3ece98443c1d70966d27458e7aa3a9ea142cc312ecdda691b8214").into()), - PublicKey(hex!("aa25778ad95258329c5947df954d43dd35099615955d36e4217c0678aec4d2e2636979c68d28fdea121f228a98683ba6").into()), - PublicKey(hex!("996401dd62d5f0491dfde4eb8a4abca5bce9634cc96b98fda7434c4428fd84a3a1b0b56551c4e6e1d549f44d64abcfff").into()), - PublicKey(hex!("a5cbee883c7aeeb2faaf9ece2f2619d2586c95862cca694edec565a440be0a91e0655b172b9cf23c7c949b1d7c015b11").into()), - PublicKey(hex!("92158e73fcf8486c92e84d0d2ecb093698354764d421280eeae8ac0371049f490d6f21daeb3581a8a0a7a0e01d8b430c").into()), - PublicKey(hex!("a2e4d6430813aac19cfab8e48a7ad09f35be25b12fc73b47e8afda8e711356b825dc54887ea43a49bba7fb6eea992349").into()), - PublicKey(hex!("8305e4f678a14d6f2e2ddb55bfb411591792c973093369965313bb103608802a455c5cee359a9f21fa88d34bd4c3b979").into()), - PublicKey(hex!("b8632f75d2c2c5cad531a85ca7488c14ca9159a2ec6f619e1e09441adc0984407e8e2b63227a989d704ef5f5e51befd3").into()), - PublicKey(hex!("a313c4b427df1a86727265386c031c25489140846b7a98dd6a43bb519094c9b103a61713f9a836d091b26e95c9b8f34b").into()), - PublicKey(hex!("9107bd3f48ae28afbb692410f542ed2ba7b345a112e0f99e2a623d5ec1683e151c342b5e0c4c69f0f783c66212beaeac").into()), - PublicKey(hex!("8cfce7c9fdf489170fd783fa96e756bf8da427896da8ab57a198185f9473410ef408397f5b153702fcac98ad13a79c89").into()), - PublicKey(hex!("91a374c9a89b97ddd2b2666b6f6add414c7b799581052ff2e0fb6bb1f1b15227ec20d05ec3db7d70f46c4afd11a08cbc").into()), - PublicKey(hex!("b881b33a7cdef8b4faba7f25a04e0ab2a84c8f9bfcffd0998782922299b00d6467114781d73bacf7ad6d38c9b8d636c0").into()), - PublicKey(hex!("829dab2bdf70dbab8b0fbf2664eb6bc43c151d307b8c092f2cf6416dd7bd69c6f02d0aa2a4072834285f324f5a1b1604").into()), - PublicKey(hex!("9829095444c183132b059816603072bd5bf0cd0d8de86275a18696524efca7545ca1ba126326d4a8ceec119afd026773").into()), - PublicKey(hex!("a1494721032bd0bd5c2505b201b453d9445bb9dfe07111c15204353cbf6e19b960950421f36df3b84ddb1a5ee4bdc78d").into()), - PublicKey(hex!("ac625c1f77b218ee3bfc872261827650d7814808ae91d6f84592c8d8febbe1df5dbad667f45c19667aac0b00c3d03c00").into()), - PublicKey(hex!("8af162cb7276dff6484d3c8b3ec69737e7cd20c1b501bcc5fdcc1d673aa9c33ea5fa56b7a37d85e3fed867af38d2b5b6").into()), - PublicKey(hex!("86481478b9c71d5e2189b0f8757932dccc468925f0ff3bbcfab37616e04dff078234fa5eb6c62607ba8040149bfab5d6").into()), - PublicKey(hex!("8671cac3b7f614370032e63dc16cf0fc6b8c43d1bc203c6bc270eac3385f71e9cbdacec90f09f118471a5a7ae9670291").into()), - PublicKey(hex!("8c29132235cb85ec64214f462b3d18acac3df4eed105cb460e40288cca062972e5d62098dd72f78e042a3c8a268721d6").into()), - PublicKey(hex!("aa177cc113ba661e52f018ff1b3846acd095c90c3f64cce30eedca5e3f6660da38e3a8097364ec8177e55fc8f5456e8a").into()), - PublicKey(hex!("8854d76a334375623169a816e2bb8f14d468ffd4bb771585fec42227740e05bd09be4fb286539f7e705f9c98d15ae0dc").into()), - PublicKey(hex!("a6e802c4c38ee34d875ae4ad9f38c7fa554b7e16ab0222071bd06ab50d3acb09fdb179f7f161d8f8f80c2fddda28b429").into()), - PublicKey(hex!("b518386447c773775ec9ecf557b01a077979afa57966c1b4c3e54bedaf18a1ff8861aecb561347ea6d9f6032935a6ff7").into()), - PublicKey(hex!("a684bdd2c75bd21e066e7df1cd7e7d768b211f400ca710eb6aa5c1b575e0782d7d91a6af01720913386d78de0847b3a1").into()), - PublicKey(hex!("b655c0e136e83695f0b25d31b49af0159c2f9aa1fcd4ad934927de99599700d2ea768ab62b616585df5cdece6f46badf").into()), - PublicKey(hex!("a99d071bf965760a9a4d557b16013703a4e683dd38074fd4493e4c126b8af6f6220bb1661087722ff2f421ddc024ecc5").into()), - PublicKey(hex!("b5d51947147917a1912064eca5f74be7c74d62ade562ab60d354b1fd01fba1b75b91b82f2cc127cfe4fdcc040a7f4473").into()), - PublicKey(hex!("b02b9f32d577b105dc8b6f36a804d271793c2dfa0d8a66b8f0d97e95020892def80394c1d242ef8abf17024853ec444a").into()), - PublicKey(hex!("96147cadf251a2879bbe5510a1ccf5d390d786970e930c244f769ace17c226244bf3c56c484de850597156e938346b67").into()), - PublicKey(hex!("a1f646de8238aea841757f629b3daa1c47ad54b4058459738930351ba2ddf39a2b9ad841233b1de3e88a69135e180b96").into()), - PublicKey(hex!("b02b5260032a87244e9987e9f51f2ea3571ff4d585d07d562fb3250a5513d35891e8b64bf628a15465e5b558af3211e4").into()), - PublicKey(hex!("b727d9365318dd924d437140b3bbf61374c9e19ddb666a5bac3ce231e3b7269911d27b7456a5476c61ffccd334e3d2d8").into()), - PublicKey(hex!("a15d6635984daf78974cf8ef80ca0a2d02030363b52c69e516841160c976f758e3b933c80757edbaaeb0a804fa0afdbc").into()), - PublicKey(hex!("891648e5e8809c4c66b3c2e75eda5f054d7a0127e7f71e155b45521b36745581b1843572a00eba7e7002c2dc04076516").into()), - PublicKey(hex!("a2f9d4e689c34dfeff4a7a1a9b23cdc90b2a798186deb4a37f7286895cae5c7fda3b13f86d5d70322e5a0596818156db").into()), - PublicKey(hex!("b45024f4210cfd75b21581207548ba98d00b5cf0e18627060623c5802c6d7a66c2697b439eacda857e7be9debb0657ca").into()), - PublicKey(hex!("8d5a72172783ba9d210447c45af1b225a920af6e9d78e8ed37e82b606cdd63c5c795c9585df1aeb3718d204fff13c190").into()), - PublicKey(hex!("a2452643f54269b1c6eb0d667212952b4aac4c40e82041bc6e8ec6ddfaa688ab84bb256612aa7f22e5bb1d141820fe94").into()), - PublicKey(hex!("acaf20c8193489b90d3be918d07aece660439496802a9fec182d06cd208ad15e1f67b3ac629d808fbc71d5ef864f43e6").into()), - PublicKey(hex!("986715822366e63c053f215bd488779d678cba66c5d88c9a6a2efbb5cfa65939056a4abc8e42286682c61eab3252facd").into()), - PublicKey(hex!("b4c9cdcdae9ef10855f55bc56a36bda3d76f075fe1a1be1d0d258aec65a4556d458dbc703978e576405ae379522d92bd").into()), - PublicKey(hex!("9911734d43686def7a16eb43d96e84f6c64af8b66034668236acf1936e3ee12b7b8591df1d6dd8933d84e6fbbba701da").into()), - PublicKey(hex!("b0a0cc81cd4076ebb83a2b47e00f050c9b86da31bfdf6174f274e1c32f64af37a94f0434f47c7aa54835ae7cf48ba46d").into()), - PublicKey(hex!("99de7e2c4666d71d3fd26b83f689fedd6ab16895366382ce36c70175b49af7d85d922b37e034e15dbc794a684b7d041c").into()), - PublicKey(hex!("b5c575a5291202d7479f2be81ab206c5a2e1d3d9c5b6b40962b02582c9fa33350498e611b4c1ecbe1182862920ae27e0").into()), - PublicKey(hex!("b7a4d0d1a636bd4b897d91e5ebd51e1dec470d4b7db388e6c87ae7d4066bac883e05ee3a5f81eb0b6406d1a5fc1bd54b").into()), - PublicKey(hex!("841407e7644a789deb8d799c18e3060869b1ec1c1baadbe2033bf37e051209b07484486cfc604f89434ad2fd19f0d39e").into()), - PublicKey(hex!("aac8b5be9205d1e0722fcf6502a0f30d8a35d077a7d58da4a926dcf74315c6c27b189aff0cb1310a5cb37d54d57cdf66").into()), - PublicKey(hex!("a0bc3e9851d64d9cd1330bf3b6d0e0bd22b825db2816821e7cc41d91e88546c74a0cbdb7eeb17a07a551a96609339ec2").into()), - PublicKey(hex!("b2d424629ffc924f0f439cc4064398679130da9ed43bb7f16996cb8f7f7a536201dee588daa78a3afba881e37fc8fbd4").into()), - PublicKey(hex!("96f7be30866339b81bf07692efb4491090e837d0d3357fc841242780eccd005b268c7bc98d0fb1f802892f9af4e5ac05").into()), - PublicKey(hex!("a4357e723bbd5e56418856a791b11107952cde3e4c7d46a9b241088caae98cf64e42bc93dedc67dd0eca2d70408dd0de").into()), - PublicKey(hex!("a5e02479ed5d2f2477fccddf56f3805653d60821bf1d163e707be1c158a39a933ff76d5800fe169a73b580563b52ebf3").into()), - PublicKey(hex!("8d55812230e112daa8ecb97226957798b7bb6111f91f4d80f2215d63910107f37d2b1ebe92ef58cfe3cced8c76b64e3d").into()), - PublicKey(hex!("a6eb94bea9f1b28ec853e4c74c72031cec40aa01a9a70c73981e2c62960bd2359568a7c6d464d2b10e71c054add70442").into()), - PublicKey(hex!("8804cd0c52b7f7d04c17d109cb3168c5939fa6386bbd178a8ac3e67d43420d8d57779e6a0a982e42cd9ee7763c9afb2e").into()), - PublicKey(hex!("9116ed61e6414f3f6910a9ded17f803fa4cf97c098eaf88536f77ab281be5518b32b09c31627d61c6e9d3cf127324bde").into()), - PublicKey(hex!("b9c7261302d385753a6a7ce32365ac3a1c51ab60a7a4a6d5c63aade9510e759e16f5b23e35e7e8ed8f1dc28d7d3580e9").into()), - PublicKey(hex!("af7bc0b6e87238b9920f8af38c76a156317c4cf0ff2a2ca8861818975c5d8b7fee8ab7f843cae182341843a8a7cadc0b").into()), - PublicKey(hex!("94cae11811062358ec48ced4df56f88f3e1bb0eea296307f53e73de79b9ce48a06cb3d76eb4c152052e7b3420bff5bc3").into()), - PublicKey(hex!("82a4f36d5865d85ed89568c2ad190d6d2b252e8b83595de881f970a69c8baa42b1b5601182bb70a8b2fc284677210e02").into()), - PublicKey(hex!("8f3d70694fe5e86e94f6b7e59cdc5d3ccab8e41181bbeaa7f7321318df278ad7e85611faa8a5a4afb599cd67ffc681d4").into()), - PublicKey(hex!("81986385f4bc07e775733c3e79a5d9625a7dc4831a23b390ec65dc91482d4f58f84463f260ac292d4525514918c8ff4c").into()), - PublicKey(hex!("ad054427eae1a29bb6565039b1f23ed4810344819cb847aacd2638761cc3a0246bf4069b660636785c7d51dbc19c7786").into()), - PublicKey(hex!("8fa62b485e3be46ee107b5f7748373abaca5ba24d2c60df2f9fa0f12946828278ee93d5ae236d5f3c9e046b1d9a29041").into()), - PublicKey(hex!("ae43cfd328bd6620ad0945739b561e120cdf00801e51103fab8de7887b4cf037ef63fe431a349588f7f8ff8f7171e193").into()), - PublicKey(hex!("8741c7b1315ce083cae37e797b115c6bfae09a0802963c05e4d141f4d3bc1b5cfc4df371ea070db40382518b5cbc64f1").into()), - PublicKey(hex!("b4214516b6151a9ea215443dd4ae4f615d994d766449eebf94dddfb4af3cf6ce47ac81375711c51b2b0559d44cde7640").into()), - PublicKey(hex!("b74ed4f8f673ba4a69ca8481d70ab1e672bbec5244f0be2788344671971d4ddfae33e6edc272760c5db5059abd887c91").into()), - PublicKey(hex!("acb93a3a3f8f24adaa99e46d60d1751e8a3befaaf73f0276ce1637fad745e8f572b68c09f004839e5e2695e1322c099a").into()), - PublicKey(hex!("8411e66cd8bccde3f58628cf4c9bbfa1114a3cc4111ba29c7fa566b759914267da36728409c779a4f5bf9da97efabc16").into()), - PublicKey(hex!("ab2e9690ef0c629a72286f9a7238cc15e71bbb672fc8fb4571cf268db533b6aa4ee70ca6056219002807695b85611f38").into()), - PublicKey(hex!("a8afb9df00edcce86c3d3408df5bfb01ecba0e7bbbf7c263518d72d883b938c8c6aa9f13dcde7e947ff29e93fecda44a").into()), - PublicKey(hex!("af295fe64ff53f14c49e79d15fc0337a50bc6f41d64925922a5948b280d5a201930d34be85a37e48bd49fc3b6382166f").into()), - PublicKey(hex!("8e5f887457b984cadfa3c80b36f755678cf3cf304529efc082dd6e48c908366df5dce3966d799b22d824ee998c3d4e88").into()), - PublicKey(hex!("b110ba5e5bec088c799964030b83fd61fb6f03e9e96e959ad3ecea5bb51696d7717c3bb20e82c4d8940c63e1fc118198").into()), - PublicKey(hex!("aa4b560a8fd436438ca6f40414b600e796ff4af5fe67860bc525c9d6fad0eac34d7b4ea94c3c1b4b80b0964619cd7e73").into()), - PublicKey(hex!("a4bd8ef6966b6cd42e3a50f2c86eb470675dfc402b0d1e4ef4f320330272d8fb4461865f53c62b7e84baa06f382f1723").into()), - PublicKey(hex!("b378357d1f359b4bac7fc3e3fcbfff5c3877ecbcdf5209e177210fd1ee5f2b2f4a24a7c28c46bd4a92a59d5178d8f78d").into()), - PublicKey(hex!("a6f4aaed1cf96dec8a96aa929bcc1ec1058d6d3d90ba578dfd8f77885829fcdce1126baa2b71c2a7f424b62a52ff968f").into()), - PublicKey(hex!("b61ca20b04db1be042ac0a5a9a444040dd4d246eb44b439ff99e03e1388956a4fb7f840c67559cc3e8f46ddfe64e8264").into()), - PublicKey(hex!("a409eccecbec9e0c4d70a52321e826bbcf2350f53662f59ed30f16d5835e6355e6ebe2d64f113d1141352b4e28eb5542").into()), - PublicKey(hex!("989f0e2e1149446fdfb8e56925ce2379d58539caa579793f977a5500f0e4fd46ba5e4df79f3f66ddf8ae9636fdc3bf29").into()), - PublicKey(hex!("83078d01f5d1f7182e84923f7040d0aa9be10774e82f643b784ca18ed6bc53008221a3b26893c40718624b8296bc2c31").into()), - PublicKey(hex!("8fb57e40286d26ca24d1cdada6e53b2f4fcc463853f32d0e4b8650e03d0659659be9ef4e33d18e6b5c86e5aaabc78fa6").into()), - PublicKey(hex!("891ae79c9eddc336f8d624e0c91033ddfc196173888058a4a735d652cd42bd50dd40499416296b2bf6182e57e36b0431").into()), - PublicKey(hex!("af4aa583e26e51b90aa34b79ba12cea6e20342dd071892fb667b1304a65b2fda65bad5ffa102f69f0b6c086dcb542fa2").into()), - PublicKey(hex!("ab88a5c49c8a2df332299b23537569e093a9c5bd39a8a20178efa1fafee00f268c1e8aeae92b88813abdc6141b116d1e").into()), - PublicKey(hex!("811f4c61c17f957d2bab89d221310cebe4192b37d4d88bfe607f5346069c43219e4e457c37fd04f61af68e966955c377").into()), - PublicKey(hex!("854dc24fab27b508b9ba8010aed2b9c19229ce35551d7eb769a684b2fcdbb6252fb6e915fab3fa03403438eca4f8cfd2").into()), - PublicKey(hex!("a0c2a2f398b4e48aec7d8567b3e5e32a75d22204f9d0198f11e2ecdf4c16ba40a60bf8398a83a56b193f67f4ab310047").into()), - PublicKey(hex!("b910317cc51e937f44bbb28e183665ce18f5e0f86181a50573cd9b4443049f2930b9296ee6fc2070de9f099ad605629e").into()), - PublicKey(hex!("b8f69e7454f6c539153d09bb521fb53acdeabf6dcbb659b1d6dbed4ff7c7fc31e0ab446e90107559e1f143973799ea1e").into()), - PublicKey(hex!("b0f956cd74ca22d0c7a9cad3ce4f1bbbf4dd9095a4e600315dd4aa3a30ad27f52570d6fb0d3cd9af6e85603c33a49a34").into()), - PublicKey(hex!("8efa2f96481ff3dae438a3d70621d633f174f2278b305e7a665390dcadd7d2b4dccd61b76dcd11bd30141e9885c051f4").into()), - PublicKey(hex!("8f3d4387acf587499134c6e8bd53b362fe1c2adff91508b74d02435a2046a2d3d1dd8039af164782df6523466c6459b0").into()), - PublicKey(hex!("836bd4f5a4e43f6578bb6cb48c4f7e52cf322c0e4a7de90fc598373cc5710b704375ad8837ec4e0b341fa53b732f441f").into()), - PublicKey(hex!("a2e000c7d1a260c710763ec7e042863dfea5166b82105e68de6b803d9d42d66627c9ac8a9c0689cc9adce16d287871fd").into()), - PublicKey(hex!("81585771a755b837242f20d8d59403222d71c0dc0e2bcee0185163196de15fbda13e60d4f6b6cc3c5fda00ff78b360a0").into()), - PublicKey(hex!("8e1c773042e3211d04f8c7462dff68f28c2275ac91d710d79d3d14d9db5a5ccdcca70199bb0e5bbd6a9b0de03209adff").into()), - PublicKey(hex!("8a3bcc0179c41135070536b5619f1f6eb88a27f00e906cc910942d9daf43051293329672373472c1a0bc13ae05ed736c").into()), - PublicKey(hex!("b83803b88db3f91fbcf0bd3ca692521a2c857ce54f1646940c8613cfa4387425e4e5e70d3ea473369ac23442b1ed6c48").into()), - PublicKey(hex!("a90d549a2909e27a096d97d33215c95ab5c0ae262c34bd8920417f6931e01bcfc84142b1ad25d55cb209271e0ea9fb79").into()), - PublicKey(hex!("adb3427e01d4e8ec3933999134e040053bd01c1d9ca26ef37427a55c84dc0466e89c168bdfcbfbb9fa144128046b5c64").into()), - PublicKey(hex!("b96007c6aa107be9cabc8dcf829c3c74740b77b3b5d7edba52f64983707aa53a657ff02b7c0e9cb8c7691243a60a426d").into()), - PublicKey(hex!("a17b3a41cdbc0be24ea196d38f84256405f99b95e854711aed7d881a839572700e6b4bca4f30c3b49f0be1225c1b179a").into()), - PublicKey(hex!("aa681b54511d74a8cd329366d6aa1fe0f11430a67a78caaa5ef0412545605a20410f5a6bc0584c5f0b7800f70a0f3d9b").into()), - PublicKey(hex!("88eeefc92801cf2397f5d47599838f86c0ce93ef2135398e0522e925e6b7fe2a67230c843be55a8753d243a0804254d9").into()), - PublicKey(hex!("86c058c53ce30d8c62ec83c3ad53e186131f7ab0bba1b349a191347fd5b70347d74457ab0e6586b14eb9b81bcf76b501").into()), - PublicKey(hex!("a42578e963df1cabbb45613d430490c8c4f7f940f8647df024796d2929cc706f0c6395bf2b4bc93af16fb5a1f2e2ce21").into()), - PublicKey(hex!("b4dfd1c4243616dd7fb4ff7c80e7a544c48cb2a17b8b63b90a3f279926c5af76f790cc1d6fcfefab15841572cd431b54").into()), - PublicKey(hex!("97dcf5d73bc42a52571b5bb8a0414a7d02bb9fba012122095752340a949d99d3a3a060104d1ab8ae532c7764a4f3d3fe").into()), - PublicKey(hex!("af5cb5a0250b4106c88503f3fc3b48002cacacd1c504c84bec5d3e6478a07bdf29ee6d009d7affc01b66d5aa138c8579").into()), - PublicKey(hex!("b02597748ae10ad7e5d3bf41e263093090736fd0305bb3f1d1454ecd3c796bc443ac9284bc038c386b5df72b45ec5df3").into()), - PublicKey(hex!("a60d817900e9c246a76d30f9f9f010be77f6e34361916a1af8d26533c26670d91ae5b4fa4e5f8d20ef50a0417f4bfa8f").into()), - PublicKey(hex!("b514b109d957db80470fa5a8dc7302a77399efda13e9da4648ad48962f450e4c51a88913c473341b2375ad8faa3ea8de").into()), - PublicKey(hex!("b2d59a1a4612f90ec1923169d16373df81c3a78ac416d3b0b3d122f9448a0f2ef4903b55557681c8c7820d9f4bf1bf67").into()), - PublicKey(hex!("a9660ffbe5d15e6c4695b666436f90daf19f5eaf6f74cbfdc9fc597b5e38ada095bf38d46f952c7f2b86afd5acd148f6").into()), - PublicKey(hex!("b3d5036a48c38573ca21b20ad21c9d5e8a23c512b2372e106a4e831a3a9f11fe98715ca3586af32d5aa9686d61329c22").into()), - PublicKey(hex!("b05b92a7fe1fd82fdf7f1efbf9eec4d703a1175c6fe3ca65569db56d81309ebf64aae088f60e5b95faa201ab42ed2c61").into()), - PublicKey(hex!("a01e73cd18a7971ce6735215a4f2a413a7f38dfa3584a091c2f0760c15d1ff9acb108716c93c7e39e228a164033976c1").into()), - PublicKey(hex!("b47e29c2b466d493760c885ee7df442bb62dcf39cf2014a01034dce5ecc827bb2816fc862e12b5abbee3394fb8854653").into()), - PublicKey(hex!("969c6631c4dd75c9f0af723d8c50d597fbe89f9b89e3fef0e77ce661bd7736fb3836b1c76c1b9c2b2768db5bf0cdd3ed").into()), - PublicKey(hex!("89721c673c1df509446c1f6437ded01437579e797986969bdad9d6da941b2329985fb06560df90686c763ec9afa77c71").into()), - PublicKey(hex!("a4c238a302c65fd75ebdb2a381f93c756e9fbb8bb6c0185ee010a3f434b5f05d683abda4c79bb589d63b7b72b16d3a87").into()), - PublicKey(hex!("97b99218a45dd8450054c6296e1aa140f14c6ba3309bdaad2c1bc6787988957f09cb0c87e850cd05f52536d78c68df1e").into()), - PublicKey(hex!("b53e4edbd722ab5723df58f682f8f4ad06736f243b6d3d4d933b56cabeebb0ab931d46626d3e16c69dffa5a5ffea36fd").into()), - PublicKey(hex!("ab8d3c7ca7d925df6e808b4cd5510144bcaeea6f201e43cc17319ea520612a4aeb65a039b7f39918d2a0ed326aa7985b").into()), - PublicKey(hex!("ab17fa115c8cccd2f9694015fb5bba3bfa7c33cd4025e44d3163ed2dfa298326f75f9abdefa7e66eac91f90acef1bdf7").into()), - PublicKey(hex!("b2a465923762dcfe26a5216d4804c7168eb2361e9794632c632a412b28a18d8252592f94d3ff515daba924ce6a541b85").into()), - PublicKey(hex!("944e0d66cbc9f0d2c9c35f33700a13781fccbad0593336fd947c8788f86e55e48445aec622a26acf07331f4159056e7c").into()), - PublicKey(hex!("92e3cd37cacabd949bda55fde18a40f58f89d3723aeeb2eb539fe8cf2d5c11044a8b63c58df65772450dcf561367333f").into()), - PublicKey(hex!("8d132145516659e2a23cfabe7989217425f7fac4b748078749e90b0875a0de4a11cb5e68c4cd7aebcca3f5d74912fffb").into()), - PublicKey(hex!("a325a22c07984652b7774ecba8ddfe5ee3fefdb91bbe150588202b3119ae337449a2637a0d0fb239a2a35ed9e4b3edc6").into()), - PublicKey(hex!("9475f462166d0dbb31613c021921186b0360949773c8498ac8ab2b53a5e592d4d0b1f33305b3c0a481300fad4b459f31").into()), - PublicKey(hex!("b47978d384d84a07376c9e0fe68c5ea4462d46ad6f774265dc62f69fd35c575d243a87b4a7a288bb3d6414110e475ecb").into()), - PublicKey(hex!("86d28baca1dd68eaa3aaa92b50d851706dafcee9021528022860b6b8bcb8b88547d03afc85c9fe866b5bc692f2de5e21").into()), - PublicKey(hex!("a092b9b4c62894a1c02fa66d6eb41088fe95627994c3a83c8f8fd6a07ecaa2897cb753f0bf2d5598be647d2279a6b1b0").into()), - PublicKey(hex!("a0a7b20ac27413413544cd23bc970da68eea739f0e3180d4f736efd9571642d2ab0c72f086251c3d9317e6b2ea708745").into()), - PublicKey(hex!("aa30c27bb9c6db7dca55cac282fffa625a570cb0f3aebeba824eea41b5d02d056dee645ff8e3510746a55d51a65efba9").into()), - PublicKey(hex!("b0fcdecd437e69b6c8e2d0c9f3aa8c754d35aa62c342de3d030f6d6080816261ea8c69b1f0f6123cd6feae78e2a7840f").into()), - PublicKey(hex!("a740611fd2393c66bbf6e671d5cab203d41c906388578a62c4f1bc2fbe63a4161c11394218a312737c1df23e573803ef").into()), - PublicKey(hex!("8ae82d8429a125c8a297cb4a049708ebc5886be12d8baaf8b9152f99c15dbfca9bf443a0e034d0eec72837e6579bcad2").into()), - PublicKey(hex!("b3312bedff432b1db8e78956400decf0de9a49db58f220a8f113f43c8e105dbcba9a5ab08c8d9cba50bc487406162732").into()), - PublicKey(hex!("98ce80c75d4404f67b91f2cb21d37d979e9881d173062d9f4944120c9105ec5a94e07b372f998b4faa8ae34508e47ccc").into()), - PublicKey(hex!("b53225a285057c4a3c8a9d4329cd8d086d7574db4981e513795a92c1c3f492b0f0b36bb98967d368d8f9f1a70f2e9e93").into()), - PublicKey(hex!("b1a086ea86bfdbbd242b23d9c8f29220465fda37442f06eb96552572676cc1b849411cbf207b8c279017ce01637a68fa").into()), - PublicKey(hex!("b211ea202d728b85b6c1f7f5c69b54c8b5f109422450562b0a77f3fde4bf7d56586971dd8dd3b63e211c1056c7f56c0a").into()), - PublicKey(hex!("a2abb29b9cc096fd4cc332c7a8b6dc84f0a21068a4190bdd6a72d52aafacd463c88ddb4f1bde3f597e08254a8c26f318").into()), - PublicKey(hex!("810b8abd26443c8e74ec0d0038720e09dde65a8f70afb696b7810d0c5577b29b17ff72e9f393ab64632e94c0113e5e71").into()), - PublicKey(hex!("a1e3b1630302e48fc8279bc0831cbb52673128dd44eb384b9812bfda6c730548cf825312fd42990d2ea731c520ab2afa").into()), - PublicKey(hex!("8d4dbab3ac64d32caf4c1de99375c38399ea83ce985cde8e2ca0686a91886fa3db7da025757a4c5394847e7bae0ac63a").into()), - PublicKey(hex!("8af3a0c287482ddd85e10d4101d59eb41ff87b956a4c3e0d40b67fafb87bdca1bcf9ea3e27839311acfbcbca079d30de").into()), - PublicKey(hex!("b981fbfc0fdbd3a1d1d46a88c24c679f0060d90299429ba8cb064f161e49121117f5b66f412c3c0b9217609a990d7d61").into()), - PublicKey(hex!("b3335b0a25218df23606047ddb14b99e815ab3f62bf3aa030704b4b07d5b34513b7cc9c417fd66a0085f45a6b191a5b9").into()), - PublicKey(hex!("ae1f197c17ffa4c4dfe26df7305e9fe74ef50ba2c06fa067518e8fd107f8417a9d26f8e60e88e6e4546ff2710434ba3c").into()), - PublicKey(hex!("8a9310197817aa1d4e417f10fbb2d020b33cc1f4f371fc80401616fac38bffd8c622e2e255626d82bfaec648762af9cb").into()), - PublicKey(hex!("85907d0ab7c55fe7b0632cac024bfc806bfbf25adbb74eedb5c29e534ce756fd448e9fd28e05293d687a7773e1410fc4").into()), - PublicKey(hex!("a1748759795830d9cca88e85197a1318c5d1056d3f340b53b14c400d3d0e2232409013c963d17dda520d48e5d150ccac").into()), - PublicKey(hex!("b686a253ec5b90503de67691f1e8be1e4f38bd457ef97ab2bb3f8afd73362856164c4a4a88b8362c99e249db22c6b704").into()), - PublicKey(hex!("b3aa2101137d4f818b0f9ca1e713c35e14869fa030542e95ed3772822d7ec5da82cd10d8ceee66498bc794b10d22f6e5").into()), - PublicKey(hex!("b6beda27458a1f9df1e4f71a6d9859941f49db7de76c955cd10783d7b995778a6ed7ccd196ed88106de43baf65362fc0").into()), - PublicKey(hex!("8b73433bff97ac9a75d9abf6dc3b45af7392838afe796622a4fb9460cc8b70f25baacb72b8010c804bfef86c475e91a9").into()), - PublicKey(hex!("98d5b096617421a9a67478966d47d6fc22cc2ed61dba80c2a18a85fc6dac9f270b317568c242a38fa9da1e3d86a97e91").into()), - PublicKey(hex!("995abae437031af7baf568994080208793be0d17846be80c450db80bc5b4eafc7ebb86fe06e88c8c742284264164e412").into()), - PublicKey(hex!("b552b8b81a3db53569d54b2f0943c7a424556e975c52121eae3bd53fb29a4f21d4d66f322dc0e39a347fecde537726ec").into()), - PublicKey(hex!("802d558d0f099a59b6b7d41884127a17532e7ec2210c57343622cfb01e50a49c5ae4966a539ce396cd4be9d053c45e9b").into()), - PublicKey(hex!("b2a8d65e7d587aa88c231cbe9eeb73c682355d2ea8db5b94a88e752c5f5d526612d38653d45a13f30da0156ae1e5601b").into()), - PublicKey(hex!("a0adfb22ff0bb5f825a48535e87bda0e08908edd027c721454ce487776dc3d737fd3bda8eb1c869d0c1e4369518add4a").into()), - PublicKey(hex!("a7d0abc4ff342b47fad9fd3cfd3c6beeb6be27c02cd732980a31cd82bff0e7f9804725b3109856c09245ebdc263cf5e6").into()), - PublicKey(hex!("a323b68ff7febe078f63c195ae777115333e2d2bb7087cc7c39859eaa6ab0f884f275ef1194c1bd2c90920cc815e4fa2").into()), - PublicKey(hex!("9854d35728578249a7f6c7513e71f5115135105e2549ee964633c758bf8f57fa9c893d8a01664ca9496856ccfc59bab8").into()), - PublicKey(hex!("994f670faa3ed5b4768a2c70f21f6232148bbfd68fccc837b93e280eb4285a93a062a4b978b2c2a74803989a373f1d0e").into()), - PublicKey(hex!("8be6ee31cbd64546085f377277354345024af6e7d197acbec766de63496107882842754a4503041aa7898982c1df35b9").into()), - PublicKey(hex!("8c2087b38a1bc17d667caf5fa082d9b11f4f939ee2d92100aef4203fa255c1e7be3dbf421fc58e794e78bc58bafd4ca2").into()), - PublicKey(hex!("836dbc57adfe226490c6b1405f3ecfc0dce1e8cc4e527e173a3744a7c6829fc63ab4a4b30a607744129de9fdab44e487").into()), - PublicKey(hex!("b6cbbee960be11bb589a5ff5d3396f722e686bac49609415a14b087d9df17d4d3578c73e4a2f02e32c99c8387a539ee6").into()), - PublicKey(hex!("a8bfcca865d5cf73e3924c2c58879b624c3c922b7762aad3306eafff2f3c5379a07343de8a89f003a62c06930fe02915").into()), - PublicKey(hex!("b125ba40e3524b2cd042021587f81575860e97918ca0efed51bcb73cb4f5001f381d9a862bc03cd9760de74f047fa893").into()), - PublicKey(hex!("8fea473a4dad36ede537b5460546b7de351a3f0f9857da9f515f737c91de705f05b173f5bc7c0aa57b92bc425e8fe498").into()), - PublicKey(hex!("a054afba52811e3e3874b105d5c58cc32d90e947332409e36d2649819a5f7f6cf4358a7fec4efa431d2b79f7f8b633cf").into()), - PublicKey(hex!("8828e330c37a53cbae125476fe4f60d0ab91d79b9580e7e398eaca3a48398d9d8b10440be29ff1d0c0767724e7e75f10").into()), - PublicKey(hex!("b14982c027aaa25ac1442617afc1ff8f8fccd7ee45aa8f7399b6c209fb5a31024be8c3d382db441ad73933a4a220b783").into()), - PublicKey(hex!("b756a35b58b0192aaff1fa9d275717473cace1a3e68ffba0b966da0661ee42c6040dba48061a1bbc7d8d35bca0e8b02a").into()), - PublicKey(hex!("b079f8de8ca654ae9e961a4ed809d66e3404025251b0eb814031e0e525be3d4fbfa8d8c6bddd2530b6cce421c78af869").into()), - PublicKey(hex!("8b1ca9733a3646b6437771b73d76e8cf972d001bd1b95564b8bfc78abe1f0c9582c06783bf1aeb5c1e0d2b263d28ae4d").into()), - PublicKey(hex!("8101f7f34107e5e7619c4eb07b8d6b566d775064a42ab6c7cc8f99a602c0f33bfbde23dcfa2bc347dc954cda180dfdd9").into()), - PublicKey(hex!("88a16ed7ec1d78568532b4d3050c45e0016d9d1b896e9b29db6cbe2d976dc9498cacb7326186567f621defb9c4ed3ad0").into()), - PublicKey(hex!("8f107cec3acce6ad6639ba9d6f85ecfe2fc59c03fd0570e28d8b4d5057ab1d0ea98230ea57fe748c5320a59d24b876f3").into()), - PublicKey(hex!("a17c8ea7acd0a6912e9f0bf36838d344e981c3e9851ae410c4f41247de843a7caf67d6cc1265d21f478b93f3cca47732").into()), - PublicKey(hex!("a109789f1b3ee6adada0c65f4ae65e141c21751ad1881ee347de052f5cafe38c92393cd63f921e9bbea8b6498c406478").into()), - PublicKey(hex!("905a7d87fbdd0a3236fb9be13492ae969086d49107a294333497a421078634b439737523aea98daa99bcf4c4eb0f8cbc").into()), - PublicKey(hex!("96a8d6525a005cbd569290c428514eb9f3968b54d05b7d41c6c48f845a71fbfac9628b31291a90f36608318096fd2f62").into()), - PublicKey(hex!("acc004a7263b159be570092d65ecedcf15cb40eb5e26a57e0584fb65526db224dae39c83249fe6b18fcdc1361569e48b").into()), - PublicKey(hex!("870ccaa2f3470273a4ac8a7f905bf17eeddb07f901d9038b324e419dcf3e9932541a90d310670939287d79a9348db44f").into()), - PublicKey(hex!("b9a9a8b1a91627d5b4672f76308cfc8455310e591c88b3d638ba962a939efa9d012a7a1fa4c421202b8ce73469c77aad").into()), - PublicKey(hex!("aec66e24360f7a7896ce11c59aedcabf4902665d7accc491dfcce7447005fa8d91c1342f313a247cd5f7a9b1da26006f").into()), - PublicKey(hex!("92d9a5109e3374d39ed9acb33940b512d585165c3cfc263e0b752449b8d7ad54c6c23a568a95395a830e4b9c1e9439e3").into()), - PublicKey(hex!("a7eace55e77cb408c04bbea17de1396273ca7246f2e4337e153aaa97d9a86f284804ac6b4da65e0126e9746211e74481").into()), - PublicKey(hex!("8fd6c6d8a117c9502f8cd89d90b467530129fdaf4bc2d1b4268a8fde38ed34163a07f9d276808e891f45e6378ace71a9").into()), - PublicKey(hex!("9832534918b8012afb4938d6731e8523f0edf7fab4ad37cc80860650c0b5a30438f7fbc4646fdf783955adff8afd1ce6").into()), - PublicKey(hex!("b03dd3044da51f68297b66c235a9d20030435991311e4d2e198f829975e57bead517eb0084abef957f1bbc23b31b5d7a").into()), - PublicKey(hex!("ad3ceb2a51b83b22662106fdc8afd3ad944357dd67016ceae679b924bcbcc012c4d689316197542fabe3f2eaef2d7a46").into()), - PublicKey(hex!("a5de9885202b2a87f83667d8225d24e0451d845189ee9468f6d5ff78b88efbe5b395a2fc305ca97e46affee7478c5e8d").into()), - PublicKey(hex!("864aec16a9b6b3b233826763b4495151bc0eb8c18c64ce159fc1230806db1c40338b40279106f5ef21d9fbaeacedf062").into()), - PublicKey(hex!("92f01f06fbdc8d6247678d980e09808496616ad77d8bce6df8d0efc7e9067bb9877be71c150cc9e291a1377ee2c14fb8").into()), - PublicKey(hex!("89bf1e4c2e20c338f37fcdb6d9e38dd81196fb09f7a9af3787efb634e4aa2f5d84d554afb04ba2b00917d8248b42faae").into()), - PublicKey(hex!("a722feb58dfc39bb6e8179ba31d2d73951fdd2f1e68cfb6b5557bde830073c5ee44864afc46fa3401892423cd1e68af1").into()), - PublicKey(hex!("8e5fc42f39327d08a611f261292a59c48e0eb3e3aaaf7b7eb0b5aadecae7a83368dfbb9ef2927e894d176d43ed4748a5").into()), - PublicKey(hex!("8f35ff0f33b39eccf0b89b067c45cc74891e543d6d7c638902f87c024f80d067d63c89e71f4534c1b7c65d0c38d57640").into()), - PublicKey(hex!("a9845686d040199cc9531712cb5f414c0994c49ae13d2396f47c77722abd0fd0f7f5472d3c9e1954e46ec0a5098466cc").into()), - PublicKey(hex!("809f958058059a2e4bf48c75e0bd803e6229952b1f3ff1dab4c7e8fe214a89db2be5bbec91c2e2d5593fe611201b3dc2").into()), - PublicKey(hex!("86d6f344f58561e65497c051ebe45b8a34445f27e247997801b3dd06f6c4cc6a073ffa87c6cf18384b20e81ff5fefcce").into()), - PublicKey(hex!("8be54b75445f775a883961c5aaaf33d050475cf9e6431f555f4469e3d2601c6ae289ba1c7e731b975578527b8958d083").into()), - PublicKey(hex!("8cb7bab37076b29f4588184e25032bbb75cd9298ef6fa275f9744ac2ec8e87cad57acd12e834d1905e06600c1e12c6be").into()), - PublicKey(hex!("b64db39b8e495b81ddf23fd87cf8cf2a86c55251c7afceb4d4a453193b471ace924fc3948b0d1984c57ef9d7aae39306").into()), - PublicKey(hex!("ae117215e0ee7cb7d989d65e3d3e6896205e082549809478cc71b47cf8223f70a414e8cf8a88fa9816fa766681004876").into()), - PublicKey(hex!("b5fb0fc564054c13eedb0ccd27801aed67017298979e2e28153a6374318277c1c0eeb9909a8601a2109f003c39f9b8b5").into()), - PublicKey(hex!("acd3f514f69f25ef2cb8fe6c204a01465d7adf7bcc7051a186f7c226bdfcc52530653557e33e7bce3e3b4de6de84eb32").into()), - PublicKey(hex!("afeef3ae99f88ac3b6dee086573281795391a116ab36b6b27406ac7cfe1d3d19f0053043b304681f22c948309fee9e9d").into()), - PublicKey(hex!("80b4e32dda024486e0d4d3951a1adb4485b6a668787adf7bb87f0c1e43b1e0db9d93874cb3ec20a2bd6d09af7b007a86").into()), - PublicKey(hex!("b3ded6f1cb567d72ede753c26e29b94157715ae260625bf6b2f77446212225d588d8090e80aa0a7c250730b37071e123").into()), - PublicKey(hex!("80c56856ee9030ccd8f6b85fa5791da52292371d8ea329939b8279dbbc21028e112a720e1a2889cb256b0aa61fcdd374").into()), - PublicKey(hex!("a303b5e8f7b95b3f3007aa2545ec68554ccd9bc213334b294ab765b0a59cee0665fab36362d2b85ceef43af4fadeb4d9").into()), - PublicKey(hex!("a5138a976bb15460a4a3c7d59e3b27934481a1b3836f105809916f5f675219e384349315b1634948d38fa155439029e0").into()), - PublicKey(hex!("96ad43376b53aa6ddb5ab36e7dd61c160796633583bbe7bd6fb1c0ce129c1a0a3838401d65bcc3887b314b22a657d948").into()), - PublicKey(hex!("8bbd96d5d90d5af61ac0bee16122fadf9fbaa372ed67352ed5727758374dc3dc1fac2058ff84a0160b414546400b3107").into()), - PublicKey(hex!("b33aedf71c73850d104725ac554192e08d7dd435c65f7032e86f226a000e5d56272b54abc5256da903739ed75403f141").into()), - PublicKey(hex!("ad91beb158875a267a2a947fa7311549f55123345022e6c08ad270df9036085f56ca9c5094ae02aa3a6a34386d57e864").into()), - PublicKey(hex!("83a8cbbdfa04092d840b365d31b21b8bac4f6145fa52cdc05557dd8787a0065075e3c23a25fe5b26daf7ec6ff4e968a0").into()), - PublicKey(hex!("8ca0d230100b64a83ea7f739f9caa1509832ff784384a2740d5c559fb4117d4c6d088dbaaaaf6a6d575885da9a951e5b").into()), - PublicKey(hex!("8195bf856a42be4bcbaa42617f235bfc5294426840903d25c3d306fe2547b5466dff350610ede21d33dfedb2519f156e").into()), - PublicKey(hex!("9350f68790cabeed94920a12ab40fb4d2b68ae64324c1c3f1a00fb6d7572e8a5f29a4c14a0fcc7538d172c55162c8aa1").into()), - PublicKey(hex!("961dfb7ec2f7b7167bbd986dc608a6fc4e2c6d74c061a24bba88b7b32c5dc587f413d519657c38753aafd37c3d3563f2").into()), - PublicKey(hex!("82f9921d7d3d2a62f5c1f87452f2bd1a6e8ae096371105a5d1bdf6034cd401395e9b325715c9215594fc12c01e8517d6").into()), - PublicKey(hex!("b49032e9b7a6efb300363213a81a1b5ad4b7dd005179b53ba7048d29a7dd10d1dabe7fbd9795ea8c30f8f279c7d0510a").into()), - PublicKey(hex!("995d383ce5720be7c44c020f1f06c3b3ed07236684a25d915070b77d6038ee43535218a30d27b57055757b44bc578e99").into()), - PublicKey(hex!("a94271d1886b1ddc984a0c38efa6e3d97c75b479018a00e3474e67fdb0def1970ed3ed232d6ba56a1baf163461669646").into()), - PublicKey(hex!("acbbfa5136ce5d83a569734dfe3a0f55b4c90362454eaecc5cd37f39b5e4102830d77557e75b641554a7aa90c686f34e").into()), - PublicKey(hex!("80d0bb10037029f0d8f8c9b9b46f0d0ff32b2198af44a4f84c8c0ace60f2b39f8f8d284308769c6075e9425d6229905b").into()), - PublicKey(hex!("ad7ebb0b1b2964a3b3caa90150e800364052bb464888ca1cd08dc7c934bc0ff8cd2a7adc1d81b5258f9dd2be3e2ee126").into()), - PublicKey(hex!("aba82261e600c4d1b4719a3dbfdf0df30017251688f2326e7e43a592be4e344b8cafaa2c8095d0e3063534eec757d82d").into()), - PublicKey(hex!("8ec48f531682cf43e48ed7c4dbf7e04915e5e217c0dd0917e20ac9ba63a4189e59fb31f75bb8eea025b8603403fb07f9").into()), - PublicKey(hex!("aa9c37deb3ed7f08eebd15adc8ccd36d3a3f0b851e6cc1a444c328f330d280dc76f1f56ce126f0c4304389cf4b7b0eab").into()), - PublicKey(hex!("b8567a2f8cd6f0ecba403aa7fb35af29941b59c531828d42fbfd0042c90292e31d308761bb4b5aaaa010514cc77d5546").into()), - PublicKey(hex!("8dae4dd9acb7322c3e50e4a8116799e0e88f83affad1da575d0b243c73938c8199138e507d35664a51e0a6ceaa6e1c6b").into()), - PublicKey(hex!("9098dededd389466af4940eb6ef188e9270396e4992cfd53dffd891e8a96b739e80f8239f4ba649ed85a1bed7c01f856").into()), - PublicKey(hex!("a6d24d97b27738bc8a37d4c9827ec79e17685bb3350d6cf7fc3b932f24bb379cae0db1fcb6d498fb1c279210d32fc1a9").into()), - PublicKey(hex!("97b81935b9662c139a747ec2a071ce48d2595953bc5aabdafd971a85e4cd88a04e57169abd895fd0716b5f1b1b7009ab").into()), - PublicKey(hex!("96a8df41518a2fb4c0a07243822399d09e6c1c88181c557e35aeba09ee91ff58c118acd96933bde7fdb26b2e11c375e5").into()), - PublicKey(hex!("a280ad0a14ce7503863aa922d0ba10a3737d6c396810a1b3b880ba7e6807f8a425f3b51f77e260bf436106f9514616ab").into()), - PublicKey(hex!("b601c5844f45b53b36cea122f0f9e23e8a6062798c045b34c6ec5e67acdd2be4f49c2774843a53eb1719150203a96f82").into()), - PublicKey(hex!("9941f0076c75a59349d7fe61ae188086913b810427d1a75a144bb1373954910f07da95adc2a475f0ab85767931ab0107").into()), - PublicKey(hex!("aab58f2af61e08c18b3e988e50d50b57228c80273db3373b8b2d2794d302d5c6b5994270a1884b6e627b2859c02bf5c3").into()), - PublicKey(hex!("8743d2ed2b45f0a5730667261ffdd0c705a6c3690d6fa1cdf8734805dd2b0c649cd7a51c3636f9e5b294139eef05ea54").into()), - PublicKey(hex!("8e73aac312ed5c986cfb54e29f2ce7d6ef5bab298a1734bf6a67d72b5e22d4fdc2aaf3b0139b3fe559d2687fa06773fe").into()), - PublicKey(hex!("8fa1238a436a73c16ff7628f26356a1e4c8431ec88ea1f19b64504b009d4189a2809a850d1095a724d6569b038d693de").into()), - PublicKey(hex!("894d24b00ede02cc3f78ff983e57097225693e875f3ff75c3defd5a7ed9f3d25ddcd537cdc580c04139c948081c4c15a").into()), - PublicKey(hex!("b3b515180ccb2652ed25a63c73d8bd8b02aadfc4d9d459e0fd8cd43a4f1470be0b4fd7636a3906e6b38619dfd0ecfa46").into()), - PublicKey(hex!("ae314b634d178e0b1dad8f95270053de5267b134fa53b9c8a8ba878335fc33e81f665ec9b7d40a0c7ddcbe30a38cb65e").into()), - PublicKey(hex!("8b3e812daf59577e6727136deef5d2e57a1931f44c48d1d47c107cd7a9e2cb88d63ebb046c587aaa72ac1fe8702dc802").into()), - PublicKey(hex!("b8093bc71b1dc2296478c22c193cda187c27ffd0bcb9f6a91e41bcbd9f50ba02d52734a040ceace3db3b5fbbb6707a14").into()), - PublicKey(hex!("b2f3ee32649cca7b44f6bfe458338598fcf996fa84eea1d6a44688549f86abd19d1d75552322ec7a04b02beb31c10af1").into()), - PublicKey(hex!("b46c888359aa9c3ab0d62801372beaaa8937f23c5d9cac75b6e94be28e3c9b5765a7b88d6fd4b4d33630aa772dc55245").into()), - PublicKey(hex!("913018fa5bbe2e87dc1b32d370955ac8511a2c63786b6ecb8210adbebc1e627df005fccabd48fb2c18a32ca86f52d8d4").into()), - PublicKey(hex!("90ec23b4ff0899680c0b3e1d00d20bf5b4336dd2ba118cdb4d45950fd28bbeca8efbf3fd45a6903b9d2b95d00be4344a").into()), - PublicKey(hex!("871f36741675ee113577a93105ad336e2587eda8712f2c6a6f30c62b06f7f5b95a1900f64cf1ca449d68c4839b7cd5ce").into()), - PublicKey(hex!("b25a07e9782e71713f30cfb483f8bd2e6d21c4eca642c87c00874beaab7554ea86f2a5608b0eb6b8956f74ad3fb6a981").into()), - PublicKey(hex!("8b5a4f62746158140fecd73c4d16bc3510564e9b366df0fb34ab656413bf9aa9c9e4626d2c273729c78b0ba9c94960c4").into()), - PublicKey(hex!("97dd2908e63e4ad680a93eef50cf9fa79cad68edf2db11918b3fcb04fe7a9efcf9d882fa0853c217cacb413e32faf848").into()), - PublicKey(hex!("8fa64df5c9cce4d37dd10fcbc182982a75873c4142758d3aa78399b157aa6ca74986fcd2dd304e273eeca659ac622819").into()), - PublicKey(hex!("80ce8d0d7cead521a2214b198ee981d331da42bd9ed14e554cc8e3ce5857393779cc5e6de64cadfe0c24defc861bb103").into()), - PublicKey(hex!("aa3f4777295ddf3da7b0f2f344cd7296f4813802c61752e04f8ede8d2049bdf5fe02fdee6e0d488bb5f96d3aee952e3a").into()), - PublicKey(hex!("aaf21f60655eca3304b3053b4fc2123db3587e4a091ad229088256ccc398f443321c0258917419f301ab6c16c63232ef").into()), - PublicKey(hex!("89d7e1a77c77609de67110c47dae1baa79b67100274ee5b7234386681c657572caf14ca5f57efb0d484c0269580bd1a1").into()), - PublicKey(hex!("b8a2150f654afd7e9f2d186d327a6444bc8a7f65aef6476a9e5b588204d2ef4b904a4b8f76933509067b17a9de7a8726").into()), - PublicKey(hex!("863e10e84764fb383f63e8d8441e5a7746faa168bc51641d8fef6492c4be10bb1587ab4d529cb92a89980886c5d296bb").into()), - PublicKey(hex!("aafab1f438d1272fc98494aae8834f564233527fcd70b14fd643c1b66690385cb5357ddddf27e0a138ba5e9c2b930915").into()), - PublicKey(hex!("99d352a00a34d091d836e51d9c30c92f15001d24ae036715fccc40b37c2d704bef0126909447a0dbb51e0c34c23eb7b0").into()), - PublicKey(hex!("83e54312f86c0a5c7d002f2605ea9d914bff9f677d63c539aff5e71c039be0272da2e8ec4b2221ac11fe0328517094b5").into()), - PublicKey(hex!("9135b68f5f39b4bf3e262568584ac4c1920d12c60c6d1b78729431fa6e70a6642bb963399a80f35f5f513eeaac48ade4").into()), - PublicKey(hex!("b111a8b4cebf898af8ce43ea6a4dec1a02a9707d181b5343b1b2c2299c4619a7eaaf5222febd3a53b3c1fb049b4f7be7").into()), - PublicKey(hex!("b613d5f4911ae12d1a989aafecad0c346d59023c01e0159d44ff499b3d01350d7fa9e59fcc6f86e6942ab5c17dc5937f").into()), - PublicKey(hex!("887a90675b2e03032e9d99897add452f27e29fcd9aa406787de7d6990813a3ef2f68da7d3f4bb97d693e00539e625b92").into()), - PublicKey(hex!("8fb8ada4d0d840e491426ff423e618e9f970777ea4d9f5788ddaf395fdc6cf4959ad6e457a5b8117ae05e3287a500eee").into()), - PublicKey(hex!("b225ed3ffb4b67b9c8d229768c7e51f2e026e6d9752538e7990e543f583aba65e65fd04951cc93067ccb48087b06b6ff").into()), - PublicKey(hex!("a763ae8e7246403caacb94887782887f1706df6a2469916855971abc7e631a6f354c3cf161c0578217167760d6e45fef").into()), - PublicKey(hex!("99439451a9d2b41a1d3bd014de9d0f4f91104ca7676edae2a77ac8b551df3d535393c7d758dd35be71548d3476ebd3b5").into()), - PublicKey(hex!("80d4468cd18626ee23cdf490e62f8ae72211f03c7ba0f5acfe267f4f6412021ec251cc1fb6491ff7122e60b46dd8de7d").into()), - PublicKey(hex!("b11b2408b3c66b588091931ab6ed8e4e341ff92c400a6da502d26deffe60f50c508fd2700ad945a89e30897a1c9ed36f").into()), - PublicKey(hex!("a670c4ce91ed3513487d4340914490e23484a99af144b7e1e1b7039368e0490ff9baf6b00607bb4b875dd342b50088c3").into()), - PublicKey(hex!("821006c1ecae5aebb0104d7ec5aac251df0de35356cfb746cf128b770eab158585463009c2aec98d5c414d8f994eed96").into()), - PublicKey(hex!("b55fb6db345697979f2139f0989402d8f588b63f36cd0c35f17267f381a9c81d04c1020f57d912ab684a496c08a44b90").into()), - PublicKey(hex!("a5dd99dd96643a950eb8f7f7a0a896f4e28ef0445de53e90a5356177be6a01cf80925709abfeab01935399176ac78459").into()), - PublicKey(hex!("8bb370c2fe54cf0913e3caeb2dac9b257665daf0a2df9d3dc2a2ccc242b63ee59e01f56f1ac4aceebdb756bf27eaf402").into()), - PublicKey(hex!("92b70264b3b2346d16b2ec9006b846e1ad2cdea76cc6077a12ac5d763e4171542825e0bc60acbb407eac3b4536d56d71").into()), - PublicKey(hex!("84b00b3c26f53fdf3d259179f552a75a15271be0ce3fca705fc7f3f1b6d127b3a34ff9da20c031691fca48e0d25a76af").into()), - PublicKey(hex!("a3b5b45d41cd19d6772aec8b12a4603899616df73c5ccff5ed43bba3a5e139375f3c34aa4a35dac5d19bcb14e709038e").into()), - PublicKey(hex!("a0b50e17eea8f7a49db3c3ee036e5275acda5a63abaaece7962cdcdb551bae9c9dbd6dba3b0660ac87b70f118d4ccfe0").into()), - PublicKey(hex!("aa213ffffa9fe9a1766540daecf880d13128893b993f3e3f820dc158bf6e63145661f4cde8dee54e93eb3e72e4873a26").into()), - PublicKey(hex!("acea701a092a1c20a48f82656dd104e5df953fb63f6456a9b6f92c651ceb649a66cb809230afdbfeb97beacdd212e4f3").into()), - PublicKey(hex!("996a0a56c4ef2c5c3c89c04d33b753d86b16bac796c1a245db0dc41e64e486e33a48ef95762a1d3b96f98063f49a5867").into()), - PublicKey(hex!("97581d036fe8b7b8ea18f257de7aa95b75632fbb946edaa2bbbf63d0063ed4051ac72263cc3428c0c2e4bd2668459763").into()), - PublicKey(hex!("ab439633e1b6f9c25053dbad8ef12818f86761e87544eafcea2b36f8764bb5367d315b1ad6a163af04426d8fbdc8fb50").into()), - PublicKey(hex!("acc80166b5e68e9bc340c222d9f29756ecc2d12e2eb57c95c5cfef5b80a70257c8243b987a45010810d97a97df16d364").into()), - PublicKey(hex!("a384cb4d518b2945966ecc2d245ee47b1461faefe20a011cf715420d9f57a944e88518f6f6c68263eeb646670bf3707f").into()), - PublicKey(hex!("8333a50d29d11eb786c65e8c76628cd65ce9e6b9ffab232e835164aa6ddb436563987e7a094ebd5c59af546fc6d24806").into()), - PublicKey(hex!("88ae01cc0213da8b2f16e93f63e5f624ec4970377feec39010273476509521f121ea41d1285b5d129ad94a06a4b51d12").into()), - PublicKey(hex!("a31c771560411b14f4f8356b27592fa219b979f38a2bdfa03934205664ee3aa180085b244009da441ac71b8ca86a29f1").into()), - PublicKey(hex!("a6ca38f66896f906f4318ebb6a0b9e240689caea8191651cff8b34f56e9ef6ca0ed93bfd2d78ee6e3fc955ce9f0fa8dd").into()), - PublicKey(hex!("b21acdcfcf7d501d6d2a3b6332c58f783314a8e9f44b9c7d7923f8b93a99c14f46286baca2f72011a6ef7186a48c6e0b").into()), - PublicKey(hex!("99ef4027f3a326026a5580bed545502cf5a90779e0bb99d5c4cc369d103a63af6c89fe771d3f24268ff5c682843ed065").into()), - PublicKey(hex!("9865132e53446fde02fbbcc91c3a6b5847ee51d7cc451110d1b20f5df9ff5a5974a6f7d34e2ace2a63ac88a2b964719a").into()), - PublicKey(hex!("b5923e99f6634027647a11ca55c360aabf6286378d27ff78c210b7a6d289f903f398b2ad2bd38626aaa2516f2836ad58").into()), - PublicKey(hex!("a00bd55b111c4f1ca4769f62db79bfd93b2bba5d3fd94cbfed00355cbf61ae0f8aefc2a5cd5b3b1734d0c9f1837509fb").into()), - PublicKey(hex!("ae3c02671387461fa84f34c1acca57b503f5f03cfa24243c57f83d0d017b2e8eac875b36ec95f48d05219637519c2ac7").into()), - PublicKey(hex!("928aff41ad76179d56137fc14a8817c8f8c35189854602accf2a2a784ba7adaf1699abf241b804b220115260ebaca950").into()), - PublicKey(hex!("827dab9ee6e8a5784c583f1c771d7eade45241185b1d570b2464de062a5c0258112454c6183dca1eb406de6f782fad13").into()), - PublicKey(hex!("97db7b2fa79801d4747f5dc1676359ef112a03de5b85c2cf59907e47a808e0f9245052241eabbf47b25caf30b7bcad6f").into()), - PublicKey(hex!("b886decf1ab08c231d3221574412f93758facb4af2532ed41083c900d669a6d55cac3eb8615ae88c16c0231b6ce18c5e").into()), - PublicKey(hex!("a25e9b94885e2a8a21ae99a374e1fb6e8156de6b3c0027e3c9320b45a7c9166102ad95fbdae36952ec2c410683e71de3").into()), - PublicKey(hex!("a9b195d76f05722ad474f98f4b328770fb8fdb79c724fa760df313b28c50731f57fe96df41f6ced5afa01dada6e1fea1").into()), - PublicKey(hex!("a0d111a8039c0b9fabbc1e420234929ec6b29a83e07952f406a171a1c987f9f638df6fcecadbbf1bdd77e365c3da360f").into()), - PublicKey(hex!("995476c08488a26cd347f807bda16e4c8df13add92324272cef97d97173a21586611ade14218b1ce978b5818fd3b0d40").into()), - PublicKey(hex!("a2c2a0510d5e776ef723331506299dfb7fdc3a7ebd5d1318877199c7d0925707aaae05aacae0de40143ab7228b2ffaef").into()), - PublicKey(hex!("a47c962b7a4209ee985bde3b15862a4a4790f56b08e1d615d9e5b03b72cff3b9be434cc2339eb3d3bd3825078802146e").into()), - PublicKey(hex!("a0e9c122cd73d0747b19956149afacf92a72f746e12f044582a78643a519687623d1fba45f9e889dcb6968bf42d6af42").into()), - PublicKey(hex!("a406aedfcf2465c07ec3488559895397a6844f2c97df7e679205dfd5cf594102ad92d4f187abf87856914d325b8728a9").into()), - PublicKey(hex!("b7078904d39c12799785a0302f9e9715ad9cce95baa4eb81ecbadc9b43b061e8a3d4e20c5ebd50c7bee6f5c6a5631079").into()), - PublicKey(hex!("ac88b1d06ab40d01550bc30768d07c8cc86959434e6f379b77c5b343651266046c496bdb3161be65185f174d18d7ad70").into()), - PublicKey(hex!("95ca4c68b81cb98bfca36905702153ca53ea70dd3b907bd4737c0f1391bc66daef371be513ddfb703be5c17c0c6ba94b").into()), - PublicKey(hex!("a67195c08930449ebb867a9eb330cdabb8c1c4d22c63f6395d55a8083e0aa7a4bb4fa1e6094fcb4c6979c86f37167446").into()), - PublicKey(hex!("b0aa1087abb8e25442ff9ea770f33387ec534392dfdd4faa09422e7065e701ea739e27a7e8f07b0bc6bcdbaf129ce887").into()), - PublicKey(hex!("887f47e2d76db44baa8b25e85f7aeccc17535afe5cb8046ab5d36eeaf95745625f2dbd58d40184de15d44583b5f2b7a1").into()), - PublicKey(hex!("b2bd6b3a5823f51cb0ddbba42aa98bf695cb23315b82046ca05412bddce9fbe966fd26eb079e4466a496c447cae7656d").into()), - PublicKey(hex!("85a42b1e305d836b0075dd9cc783515154b8b9c9eb98641f2d3e40ccf42ae7ab494c3d4b8bc14fbf7b9436e51f411182").into()), - PublicKey(hex!("ae99d82553b785d6055a3d4501b1cc85e03fc1fac06e09b4d55ada6d5c7d94f28bf39a7366466045241b55d7c2faa743").into()), - PublicKey(hex!("a99c9a32eacaf96184cc59678a70758aec1cf8449a43f07b028129bf59e4a23f2c95677f2362a65069ceea2d2c779f0a").into()), - PublicKey(hex!("8a8363bcf63de18a42531b3ee9ec50b649189b9ff7b3c5e1ec71a624406a74967a4e036a615f2aac3babc279231412ba").into()), - PublicKey(hex!("b17198639b1cdd2ddd9ae0db2a4286343ae3bed6d1324f8edbd30e4de9a24b03c2f0056c1d91864910b8da394288bd45").into()), - PublicKey(hex!("a4eef40a0ab80e78e4d333930cab48f4a754949a8f495566876af5176abd6473632ca5eb924914c2e4b8bb975ff3b8f3").into()), - PublicKey(hex!("abebe936b21160e3e37bb6f72dfd9788f4024666f425b1cd3ff1b32ca3d0162ff801bc6d3c11f8434a4d7942ef3c1080").into()), - PublicKey(hex!("8e6a31f7ea157bc1f1cd24bbcbbbabf5809187e7aa54f75ad43232c8662bda69923fa3785bb1e25e82e29f8ecc91a7ee").into()), - PublicKey(hex!("aacfd982eff769bd41a4679cb4eb5082aed961c898be080c411a410d5e0e4043150e0b1a08e944d48a96750027c3dca9").into()), - PublicKey(hex!("85ec172e1de9adfe9e8dc502e1d58ec3a313d5046b2420bde2b553cbf56e8f95a7fbc45452f4a827db963a1d60743a68").into()), - PublicKey(hex!("8f07286936f74536ea9f924c14034889b7012944cd20daf73310ba391f7f929c595b14f54cfe4cfc9802c62ccf047c6e").into()), - PublicKey(hex!("8d3f96a8eec337ca12fe15b57950953f6c6b0c6be3043d086cf83e04227b7a20d740552ccba1db10a57a2357d46953db").into()), - PublicKey(hex!("b42da80d7d783a1ca5a385f9213b328cad07726d6951de01d76663745d9dd2c04a851de9a49dc069d646a58000c214cf").into()), - PublicKey(hex!("8447f82d0b0eedb86c38a43c0db2a898af74822175c10e4bb8ab46d4887c9a454ddc0d1519f405eb1e5fc307acc78eb0").into()), - PublicKey(hex!("a479efc07aab1462423cd5dc57912e1141f1ea777905bbb2a610568ad5aaba57c02402e3b25d2b752621d783fd7dfc8a").into()), - PublicKey(hex!("b7d801eff4735bfdd687114d03794a63ee7da41f9b8b866d0414e9eff900a13d70eb4891cc1fe23acafa35b9b84f6a43").into()), - PublicKey(hex!("98a08bdd88ff735845a180624229331e947b130aef4886ce71cb9a9a9fb15bd74cbcdf06b5c457e65e784991e0ead210").into()), - PublicKey(hex!("89cc6a975b8a939b56d5066fbef61c5ae58ca8b084b7ec7b87f5c887fec51dbb29bb6203aabc67ec3d19075adea501db").into()), - PublicKey(hex!("a59ea501956765237b3242efe9f07e8a78ba0aff88ec538d3d6d54e8dad0e2991ffc3ac33e9a485d8503e0e8176c2aba").into()), - PublicKey(hex!("97c7e0d555463d3eec25332779b613a76a80a58e79d843314a3507e4da88b59e3fef79dd6c22404866308e25822f9cc5").into()), - PublicKey(hex!("8a0ee7647b7751e4504813f419ae6b507734b7272a80a434d74cd0fd904908df3ac03605ee7ab9ffc2c948d02641a231").into()), - PublicKey(hex!("92cad4a2a986fa0840fbdd4bf4fc84949c55bcf4ede49f371321665b5f5be670f8f9b274004b9a90430c07b12496a4ba").into()), - PublicKey(hex!("8631fad25dd9f59044a1f1dfd8f758f1ae8cbc7187c28a7d0040fc3c0bd401c8f72636b36f61fbed0cd793ee322ef457").into()), - PublicKey(hex!("93c4d674fa1c7a54ed027a590afd5860754dfc48566a6b6a64b7c45569bf8e6f12426488779e75f6f10218e2e32404ae").into()), - PublicKey(hex!("a52f19cd98c7f620bb4297635998f262908501588a5022ccdf733f463d9c240733b41e770ddff19f716a130dcd62e6f2").into()), - PublicKey(hex!("98bdd81650db9b8cef44ec5c0014212dec415e71d96fbbe82d412468c70fcbdb508b8f009b83b1f63eb09440806107e0").into()), - PublicKey(hex!("a99c9fc1d789eabba6c2be5fad1bf3d38bd4f0517796502c2cbfb1173decc748863007aad15c9ae0df72ea098a82f3ec").into()), - PublicKey(hex!("8301741b802e3261c2fbb31a1c8ebc3b0646b6b1aa32a0df4c590d5112e45d7c32b098322c430859f74c3541886e5cfe").into()), - PublicKey(hex!("843a017a6dddacc204d41707ef328035cf276625beb54cc228c43adea843d532fc947e7e24c0ceef6345c9dd8a2155f8").into()), - PublicKey(hex!("85a729df4d0112cbc7d15abd45ac9ce3d687cf515f6e1d4a9423a080bc0e63e352d48148f8d24a91011caadb64db9eaf").into()), - PublicKey(hex!("914b7d7be374bea5cb27fd208c6cc8969671e7d05cb38aec484b8be72072397f1c293622deb72db55ac81d02942b6714").into()), - PublicKey(hex!("95bc325e72f609a32b2f91df8b19e62cb94f53dbb5abaf1f0c47d7a1b99b7c6e70e4c490bbb1e6fc13fe6e17e6b0b4e2").into()), - PublicKey(hex!("971d0134432d38628e36ee164eb4f1396244689d60b7b4b4146bd302636cf97698d53e50604e6d2d702abf874483aa35").into()), - PublicKey(hex!("870b8a6349a8f1e848f18094c1a9139b94e9f41a4522059663f5a23e038dbc7356050e6a3178caa752d2e968c6ddd14a").into()), - PublicKey(hex!("a03f5a1122018dd0925456f24169bd78fa0451c4c7d005b95d301b9fc9e71f297803fd47346838eda26bbb23a1f393a1").into()), - PublicKey(hex!("b7df50fac8570f66b0d3618e157346ff30a1d80876bccce4fc59d0f4746cdf2aea64c0848916a8ccb3be57ca6681c206").into()), - PublicKey(hex!("ae6beda3480ca83ff31a2c96100332dd322cbd8084e24538e4da762a0f57764dd3d53ca0e60be73e909b2b6ed38933d3").into()), - PublicKey(hex!("9018c0f26b6cc9fbc7299de32bf6539da6f782b7aa88003862651146ebd2329fc2b3c363e53a8b6a492fb25b34079a6e").into()), - PublicKey(hex!("b6568bbff45feb5d4ab56fa0de8cdf553f3f55e6397300b54b4d9c9896d29d3624ff2b147669eae16687f4efbdb9281f").into()), - PublicKey(hex!("ae7f790bf8f7967424531d927e487b3aa7674d15af1c48ae4666c4977b21dee6e7677eb396face00cec227f971c54153").into()), - PublicKey(hex!("b6007c900963430fdb44dc4eaebe45ed57a28f930e862f19fe51cbae7d28bfbd74d4419aa5e89e7ad605874e79abd74e").into()), - PublicKey(hex!("8a0e314de43adfb794dc62f1f38179db784d0b21bc9e7e3b68aa1564faaa552ae0f7a625c1af47d8d71b6d4793de05ab").into()), - PublicKey(hex!("a272117258dd25abc0b2b4d82665f603195eca4ec75331e3be5cb8a7c68265a3d3f564c95d1600c92758854ab4202f30").into()), - PublicKey(hex!("a39bd0f658efab6769e1fcdc3ee1f73b4ddc8a8433a680bb87580a9ca039eed9c77e99154dc9ccf0c0653661c6003a36").into()), - PublicKey(hex!("818954f810fc9a23c26b01d5d1df5cec6d233ee311fd10f42410e9dab0253525eb722d6fe7c7c49ce874ca23bca514e6").into()), - PublicKey(hex!("a5e2d68cee00a1113ca3aa7b9580212925615978964ff44c925d0dbd1cb651d02d708307ebb737383659c3f1cf126f99").into()), - PublicKey(hex!("a7a5824a624e9bff77cac810356e3a0465101fdaf5c45f261314684f4ebbe9a0a3216e720e10ced800f35e213508deb9").into()), - PublicKey(hex!("a1c170e7f717e1c968190f7724a7f65f74ed937964ad5b479710898e4062cf14e42bd82fa7078cfab131bd414969cb2b").into()), - PublicKey(hex!("8a3399e1c7e823265cfa881e2945471737f49e57b6588435b7c5f864af5e7fd657236769283039fc6a4d19c3f8a7d446").into()), - PublicKey(hex!("a048621fefcef32087074d156a4c21596eb140d3afe0bcfa1554a7051fd891214caea2bb08367679459c9a1b5ba68490").into()), - PublicKey(hex!("945c7cfaef7daf66600c3d2180cd96dc826f16e51e63302229e3d5d5182e608b648855d6065aa417fa45a13f547210f0").into()), - PublicKey(hex!("b5d0baa42f71c704c3aff972e71bc4c0b27738889f8f2fe287fb9f8a1a612bbded227ffa7c8c2316b3201232d95563c3").into()), - PublicKey(hex!("807fcd5b6e4c45dd212b07faecb9e9570ceaf552465105763423203e24a81af829772ac016faf77dd345846eb196b906").into()), - PublicKey(hex!("a4119c35d4413dfba3c53985d9a85ccad283b4aea12d006c02e5ee34dde5f63566ebe16a5f2364fec41599590178e8bc").into()), - PublicKey(hex!("93641254d7244449df1a3fdc5854920cd657a2aca3bc1c08c928769d68a21c9017c725650ab7b4eda965fe2cdc2a9f85").into()), - PublicKey(hex!("a435e70c98cc0381ac1d048438b0f4ac6cfb06d5ccace73f1565225867446e4f306572ecdf4b7d8fe2ee496274aa2329").into()), - PublicKey(hex!("a1b57422956839188ed7490eb270b5c4171bd932fb5f7acafaf066288e8ef5f606de7d60aee350fb211047ea4b010c55").into()), - PublicKey(hex!("b4bf1e7d116e2f97ee8460fa0d0a3c18461dd32962f52cc1ab93440d9d34972d0160b9d15ed6cf77133c751591bf1e1f").into()), - PublicKey(hex!("91c7238db88203baa821e4f2082e217dfbf9b5cf15c3502f186fc250a0680fbac1a52aa9f81ae65ea3befe64ebabe9ee").into()), - PublicKey(hex!("b889f347492dd365f29b3c8b70d7d34908ddb5e0dd53eb54a1696a1b120b9595fd1c71e82a600178e42aecc028d68700").into()), - PublicKey(hex!("b7a7777e8c64c78fa50a28af53e6a13846a28c00b882d47e1f614dcd9d23326e82de960f24737ea087c896c5eb66b28b").into()), - PublicKey(hex!("a929df1583465174bcc69010f3ec665726ad0b2543a89b5d0cbcf1ff2ef4b7617b32cd034c66341f4f6d5522027d90f5").into()), - PublicKey(hex!("972e39f2f85e5bbe8f51bf2261b49d913a44213aa096f2a38975044ef284e112cda9867bf1e7413bf2fd84de17a46654").into()), - PublicKey(hex!("b4223ec897565c998ac53d5656d66defc3f079602e8c3bd44bf4bbc95a705d6d58022a5978947b02d1ccd1047010d173").into()), - PublicKey(hex!("988969ab38ee989490a540344ce9f3ba1db11f7a70e6143e1b3f7882051a84d5a9c0e7ac87dedeee5b57a21e9ad6b6f7").into()), - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("8f655c5ea450ca6642be30574a2bdd4cb674024a3c8a4705219098cc75e005498d2b62d6595c56efde6760da64078d9c").into()) + pubkeys: [ + hex!("a7e8e3ac727b352f35c6d775177b7abf6e8c417ea64d48843fa20a97dc6b4a2ab13534e1ea7e82f4673ab9ac5e1867c8").into(), + hex!("8fe2698be132a121a53d3ccbec44cf128693ae779d24b198b51c02c2992927ebbfdd29e3fc950d8a06bb239f5fa6a342").into(), + hex!("b340701986d59d4ff5dc0e2c725c7cbf1fcc78882f057d5524b41ea881ce5d63bc6b67a99efb1f76e6cb64af37e20ced").into(), + hex!("a11a9607daf5ce4e7eff377b926bc44f8edc4d15da0d0b0784f2e50fba5fa3d3c947e5b8911df60669b5ece7b0d22496").into(), + hex!("8d980517aeea95faab9ba54e154165ca1cad568016f420fb97a1dc80b95260dd33e86c480bbd4613a6b45d27794bb78e").into(), + hex!("894042990af1fb6a6b8ee3c674f0ef656153dd1ca214f6ed2245ebbbf269968ef283560c8f0d082301c2edb595362faa").into(), + hex!("8f66251d2efa3f5b161f63ad9471a43bb3162150283e304acd2a9c38df1c2865e3c2d52ab42fb0e30fa17c568914b1f8").into(), + hex!("84470a956fde4ce248bc9e7fcc8fcf0d3293f8c67919cd0f2cec99c117d659735cf4164cf9e89051a63c9b4198bd4bb2").into(), + hex!("b7fe047325a99316990857234f641416faf30e72b9ac53e5d5c3dbded0e244b21f8bc2a97173a2f8f7f7c7b4095f4531").into(), + hex!("afc0993213b1e5cb0cee79b059c63613c4c5f8ce590991201bc186d818e08731c193de70dba35572a2aec90d6cc83ef5").into(), + hex!("957b21902f391a27adac9708d6809a6befd7ca12796dc6783869f3f34e8a24d6b60c4e58b858ffa330325e66f40d933f").into(), + hex!("8fde4607d06a75115f5fd62e55cac0c77b29ca6d7181123ea28279c0345f5e6c7273df12a324157d69e0889cd0d75456").into(), + hex!("8abad528201ba6c444bacc7a3e8120d528cd25ca084cbd881d179b70e01ce703d58db313164c01b1c5a0711a93a7cbe6").into(), + hex!("a5edacf72d6f69cc637cb96815a66bbc61d7dd67e2a3787a23065d9ce7d42664664ae24ef0817c30b33ee626043046d4").into(), + hex!("84c3b7bc6d0da4fac4110346600436eb63871676da86710ac4eb0cb2172895a1d4d4a3db38b6f4cbf3c8a1b0825d3490").into(), + hex!("b7d570ff2be844df4bb566e6b5657cf55e50909316e4c1f688a63347433fd663196c441b7a454722f47ab48d4beee31e").into(), + hex!("b5fde0910e6c4030681a060f60bb065fd004a124b7ae0320f88cc7ad247c324d7bb6be25ae8a0b8fd48f00a82e82d142").into(), + hex!("85af33928106db4602d10479f2344d44bd9048a051d0aa71cb375314523cde681ad7229bac063cb5216ea88570ad817a").into(), + hex!("afd11906038ab5068257dad993579495080f9c242f0ae4a023673717e6afc16872372e708383ccc5f3377b0494c48bb1").into(), + hex!("8ac30146cce791a328f362ba9d03aba246875f14468b709e63ab3139c9ae7694a29694bb248bf0ecd781c8d21ac50eb1").into(), + hex!("a021597d204e479496b4aabfc38453e8d8952e8a79a1e843da06c720611248a722c03ef7d02f34d84b4d95a148fd74e9").into(), + hex!("b60da87146297451c80d8eb9924469599c1f4338a58dbb7d46adb9226bacd5e7dbe9b153b62315c82e332dcdac16f75c").into(), + hex!("a96aa204b681dc2c005567759c1b9c1f8d3b6baa9e2b4ec9020a5ed689b1025b591651a6a688669ad31827f8c9c39988").into(), + hex!("8768e956ba3d684e6ea42629d73f6494cf615e4e3b02ef7b521cc28e373bbc895144b0f764ae676244a7d79c7d5eaaf5").into(), + hex!("b9e2c729c583a6341b6a0f5f13db577fa49e2b48a0b07319e630596f62b90a433aabeccff9c257c6de103f8cbb0cf539").into(), + hex!("829900dabac47024f9407bdf342c61c8d791e0d44a79b485ece54e236cc6787e2e43629509e1603dc1b6cc154c584b3b").into(), + hex!("a9d09e1844e25892a9810db0f20d99932609849f3d24fce2834f2ede77f60d2a2c7267e23f2cbfae7677ebf34bd37826").into(), + hex!("b4c9bf28d74f4ce903a5397fa272d09c0085b5adbb3ca56d73189939c6484f1bc945d6840aebea8769bc5e45b0b1e3b3").into(), + hex!("a97c7a6f84ba137a5343ff6ba33a78eaf151e8f52c700efabb34d5c3d646aab4e35f789de20feacb5321531a87065fe4").into(), + hex!("a80cb7843f0dfe5b69c209aa8422d314c489d4ed3603f19588e1d1b7fefa77b934f4f6be163577dd7d9e30888eb9f1f1").into(), + hex!("a2a6ba8b60c11b94904fab110509ecbb806fc2e693683b15ea65948f18495799fd88ee085d07edeaaeb5f521e539eee8").into(), + hex!("97e27e88808f725a23aeb435904ffacc74fac92dcfe1dad8b4a9b70133f02d7102b7287574437f88eb2082dc9599818d").into(), + hex!("96250f94999f7ab3e20f639263ae780432ec04d54d48880c2bc7ab1cbd8fc6803bbf5907f8b7117d80e3aea4137150d0").into(), + hex!("942e02d4bf5864ee00401a1e60af8ba79ae675fea95fab314aa676e50b37dd75ad890fa0766e3362ac3bf19fa725af9a").into(), + hex!("b6b8b28d96c50d456a28cae6fe2b69e28507ff9a55d40ef799f79d4951fdac36103a47d36f7c5a0237f274fb66661e52").into(), + hex!("82ff5885b86fc1a78cfa90ac4da8c03763c88d0e9312b4f776b58d3461416e60d0b5d7fca091d3d2e90f3305a06de3de").into(), + hex!("a513d01ac867507fd060b5622a525b7836c09371e9ca25504b7751a7ffb5e51c846ed0976cb850eb68ba250fe0555bf0").into(), + hex!("b02a46760b6e4f4964d14cbe1ae6ebf46e23a9b6d30e86e0faa280aac9ae0ea2da2dea0b1a87a371758831ab82d6c2e8").into(), + hex!("817f3e3e83957e93dec44e9c1f12b532d1536849c0751622a220a27e0acde4e66cd4691fbb5e3c4fff061a90f9d93ee9").into(), + hex!("a984a592980bac71652bc1f4b48580ce9e93641de7c29dcb65d63dc095ad5fb28e2b5cd866f7f48658d5f62bfb693987").into(), + hex!("b2de2174c65e730b24103d1fba5738a826256937657591a6fbbed552fe6e8e8d6c7ef636007fc810aefd3b2817b5ad67").into(), + hex!("a517a67fbd27691c660f6af1a4b661e85dad8b4e88988da2e22eccd63829092f4b4d8c347161198c7b39605b0339c05c").into(), + hex!("a02147bdc65f13c5dee80f213b0922fda7ff91a1e3356de48861339b91a379284d02732735adb024fff4498a77ab5fb7").into(), + hex!("a7b71f8a4535e574c953e33282b12cad6af772ad0460542c0a6f9baf7fcaffa58f46eb9bb7fc20e8b83a175e80a9fc0a").into(), + hex!("b462c598ef2093f5eb88ed8860c60aae2e8056197e2c6bee34ecd3e2c89a96421280b3d7ae1d273244ac933c53640cf8").into(), + hex!("b4c717c77f5824de012d69e921504cb3c75a21b98cbeef97f8b38187c1bd8f24ac54da29c759b32b97e391dd9b76e2fe").into(), + hex!("8bdc42503f8ff93da336d9c950487324985e91085613594488481854728b02b03d448e2316f9f0310c880131d9522718").into(), + hex!("90ff3872939fbae7b6221ebcf0e481533109549ff169483c1590fc65f617677b10ab01329cbbf4a091f7930d47b37d8d").into(), + hex!("af2766fe19f07af307a42dff6484de260e51f1f76908793332ac0258917c969dbf605ecbd39f4b41cbf37f747566992b").into(), + hex!("a9b1ce53f971637f6d3c9b0432400b2fb7b57d56538429f171e8a82164b6dcfb3e085f943d5c59f5b49896bf1e03c687").into(), + hex!("b064577d2c8bbc90d57d501dfeafd4ff609d371fe3b9156a30a21016d980e46d1017151cce8750e7ba90dc4628ed5efa").into(), + hex!("829b55e6840a230ac2acc728e9414118aa2f891b3512d6569e0f18e1762f9e1ca974c6a2f7c01bbce15add80ad5c53c9").into(), + hex!("b73597c5ffd3a812e8a553bd3ad2216282fe7c1203120624b86cacb8a7421ea6807e29fac3383cfd61d632db8e3af5d8").into(), + hex!("8a8b0cbebe482dc32e56ef65fa06bb7380639430982b33d1d63b6b0958fe38b40f3a9cadbf304cf635ee1ef5adcd0f10").into(), + hex!("a846dd941e176bdadb6e8c32ef23e6150a8ef77afebbf8176a2730f3558e709d1f04a991ebcbe7618b7ce209211a095b").into(), + hex!("a31007b732db94c9b8795c84e1a553c4cd4eadf6d11b445118e07f0fe87a2705557187cda0f4830cc4134b608baa6d8f").into(), + hex!("b4caab40168017630c8aa2b8ceebbf3ac75017524279dc7b637ebde8ea746362480ae15525730a46a164a664843c1131").into(), + hex!("a87241999940c8fb64632574abaa4669e1f78206f5fcac763c8eb4f0a08fc4b4eb8804a772440dd9d38949d4d14bff25").into(), + hex!("ab529992bb29bb00aba71d378d12e2e501bce1d1a2e3040966db463cd8a996f2dd35b578bbdf709c8603211b4b3425cf").into(), + hex!("9631260b7cc849335140e53bbb30220eb8750990a3185a1eafcddf39baab9eb51d3cb807566e0057aca803e931c76153").into(), + hex!("8825e541b5389241bf80565c3818f62c1eff16b3bafbf0cfc77e108c5ec8409279a90da283c2c6288d4db1e2d3afb54a").into(), + hex!("91a416b713ed83dd4d7fb0fc0c202356c38fdc796dc757ef5dbecc01b88254cb3eb82395ca94c93da1cffcc394873237").into(), + hex!("80e79d3c1c3d04ed8ec23625d82c91d9d0b7cf2c847c7705958a671d683e698d03d7041bb2f67ac3c412faf82e885fba").into(), + hex!("8f7f00013e39e1db69780e3d2ac6442847d9ba6316ec6e9890233543d5e9e5e9e13d6de01f1a8f02550932f613bdeac2").into(), + hex!("94f378a935ba5e39ddd0a5e53ac93a4872e5c2ecd6de37b48d601d9232c76d9a3352381efe611a8465b8862f58afdc6d").into(), + hex!("8c8bcdaf1d9199e54ce64c01d594def4247d318cfaa25e03f10583da35dbf965f8583ed090dd417d1d5e90c828843a8e").into(), + hex!("b2bb5dcdc58b045c28cfb9a432896a4faa845893202d2e0411a237913874d23f3232e8e2abf8df636614a0e4f8a23796").into(), + hex!("9068cea93749dc004003daca8d814364e08ff9c2121abf1e04c233051d272410f0bc177e21032ac8a2181362f3eaf87d").into(), + hex!("947e4a8629d714492752214f26da22b7c9a45cf0535643c7b85d288749baba19832ba6049a2a1c4031bf382b56429768").into(), + hex!("975efbfb4e34b91a191f00a51dcc2817de8c679543fc0699d4043b6fb32c959d62aa69755d1399f5a4e037cc0feb137d").into(), + hex!("8d8ad83645448f8e63e26ec76c9dbebe01bfa11d8abbbccdcbc9abf32f833dd32ac14d4cc93a84aa70c9085ee09c768b").into(), + hex!("89803b8dbf715f1d5c643962c1d19a3002cb7bb64d0f489070fc0df0097845591c0d07d7460715089cb32221d022a710").into(), + hex!("b94ef3f9253020ce53fcb7a7b466e03504c517c33cc914e3dfe4353685e7e0eb7f45962e1efec5d3b04e4efddd4356c2").into(), + hex!("96ccfb2bde1c8055e4e73ed2fd6f6830343ac16f0c44b8b6702a20a0a9ddb36766c699a1bee4b6227132c1361eb685e7").into(), + hex!("aacb3053d9172a9cae8682d6c443b04dc0dc1e61c093f6a1d2aa4bc42e91d223366550b04a4f72d7592b7e5df9312363").into(), + hex!("b720f4a832f5c5c3690b47f2925f3bde24cf11feba30657f2d7f7f04bb910fcff4e4269a611a182f645d7293225566da").into(), + hex!("a3b71e15bdb3cffb1c3c293396461dbf3e47e2f0503812e8016a23a73932e84377e5520b9978521daa02ea1db220beec").into(), + hex!("a23adbd995983488814b1ea9422bbf8c5985eaf6a3c2a5f136bb9f51c7e11ab6879e15b462b49a462336fe4424b7711e").into(), + hex!("abc88c9c9b04ecb517a22cf2435a8a1316e01213295bc028a660c98f256ae2af58674bb99aa368cb074da7cff9e7a712").into(), + hex!("825893a3994804fe91c2db7829783f48bd7251be4570401e983ee33f3dacdf5e4b9fd65784e59276cd22fa6433863680").into(), + hex!("89ebd0ac9cfb3d891c6be18151843c52c41361f131a90fc569547e014aa1fd3e3c6d692156a085ce8023714cec9d6f46").into(), + hex!("9843669e01aac59485029d7cd1eb6e8a06aaa7464c5832e0e593b9e4d25da88bdae3b3d0994a84414586e3d21004e1b0").into(), + hex!("8cf955a0ef51424f14c7305f3fb342c18d025e52a3ffa06076147ac35f735a5711733843c32aad4321896e2633a76fdd").into(), + hex!("921a2900b2e63f25a35afe19c1e2cde8f2e4a7e81346eeef6c209dfd16ff4ae4c1bab98bc1a0b9598712d9c884a62a18").into(), + hex!("b9d514458e9c8c8c7b365ab64fe9b1adbd5d7ab6dea2dc2c944907fa3eb69b0cf0b04443ca718b7e6ed25b39a306fa0f").into(), + hex!("b334310c8c6061b5efa96e10bfd1014e907626bea02bf191afaf830bd1c9a4793c7517cac9b13fd79f6f9bb2510996cf").into(), + hex!("ae7f4a17e2209ec3be9f25349cdc0d6c0caef53def09e897a6ae424f7c2b74aab14738c2f9c0a2f1f2cfc83c61dbfcaa").into(), + hex!("b0ef0d9260c0e0b6068865afc3c70457ef34237ae82d1f57c72fa1a40c9b68580aef667e122c28e1aa6ecbf799f37c71").into(), + hex!("861d6ede329c29c8fe9d1cef8c9a9abfd5f1aa4e2504fe5e2c30e419ff857ee7493d4bae5f9a77d23b8309dd44570a81").into(), + hex!("b59856606d64ad072a16f8ba4765ceffe08d9abde687eed80eeaf3a0b17bbd472981ddaf6bc449de7917a951a47c8149").into(), + hex!("a19ef1c85919c6e9851207be28009ef5851adeee438d1652145b6bbd1bbdbb016f86f213a30f6afab8623fd95dba7282").into(), + hex!("a585a2ce2bc6bd0c0cc3cbcad36d76e73ef88892268c5e7c3edc92ba92ae96fd2075f5720064ef5ee750bd2c07beafea").into(), + hex!("94989b6f2d521cec8b633abd69ba60372370469740ba9cdd017a2892be122466ec46f17998438813e9b0aaf3054250c1").into(), + hex!("8d5293a363665f304bfa3e1ac13984b804cbab432cbd6255e19f9aaf2484aee5f233ce94339b09189bc4a48035767886").into(), + hex!("83e81be1e8dae75e8b6e6169d45478208ba4bcf109cf6ec9651ef018e0816f4dc265af02fab4f47cb1f08535b6a905e4").into(), + hex!("b1f261d67d5602b6542d9e9601494fde0c5f0516e64b6dd580fa55c7253834a41190902c700f1c261af3100c230a814a").into(), + hex!("81126dcccce988efed837cc09a5f231aaee3252fdbc2da28382bf670248db9a8c31767dcb9188ed1a7e5ac001a59901d").into(), + hex!("b42b78fc278c0ab6c5ddf41e935141a8e21bdc97ca6ed3171fd013818381bf86983411392d40b6ddf7ce9f4a35a46edc").into(), + hex!("8081ed92a2bdc7659b23cd03a4e4e78ab208ac5b6bbcbf6ae457c3c8e38d8cb66b6882fa1555e9adfd5c44beb4168870").into(), + hex!("8e6df9aebbafc5af5e94ad47a0954eaddaff7055f3c4f9f10c68d34fa6b5a6a63a59408f203a6fb447a721f4bd84bace").into(), + hex!("87defe0569358da36a2d15b72761bfa8cdd6531be38a63c1e5efa61c03e447664121b6fe4b6b1854924bad66acfea735").into(), + hex!("87d3bc2590864ded7749603ece2a9ac81f114d05a3f3af5a102c7aefd08509d8342699c25f309301244e627ae7164a20").into(), + hex!("a4e4a77c5c3cc5588a8e17594c72b1237bf0926f6b0a00369cc859020ac940fc658d0f6f81d73c5bcb6962504e3798a7").into(), + hex!("acbe8ee3cbd1dbd3d097cd6c0f4e905ba805adef813ba9ebc5cc50c82cb96a9ac40161e8f401d20778df9bd825e74d9a").into(), + hex!("863bdb7fd7388ca56688f9dd5695b388032bfd71f129771955150e191faba18063074db3584a3a9ef6631254b7066324").into(), + hex!("a65aa678985bdde297be4f94ff710004ab2df647122586ae63a79ef2f07e3e2ecd8c2f8b2172a32cf1c3676d61854577").into(), + hex!("90b69711231c5e7be90ce066ed325121fecdba493f7a190f16ef4430b6374906917de4a903440b0012ba59ef127840ee").into(), + hex!("b107e95dafde20f4aacb66ba468da816489ad4ab3d2071067245f42734e357ecc815ce053645ea7205053c66b509d5f7").into(), + hex!("b68f16ded8e64ff88295d183c1da09f3a089c52dd3fa8731a576971eadf04fadaeba4e4f4995e5f1d24b88ad42e804cd").into(), + hex!("b2ec93bc192526ea6f35150c76060fee0689f2e3c9d07338f96215c5ee104d12891556b8001ef0b088967bf014c068cd").into(), + hex!("a84316ce6764e6f9a66b57b28664919ee48636e40df3ece98443c1d70966d27458e7aa3a9ea142cc312ecdda691b8214").into(), + hex!("aa25778ad95258329c5947df954d43dd35099615955d36e4217c0678aec4d2e2636979c68d28fdea121f228a98683ba6").into(), + hex!("996401dd62d5f0491dfde4eb8a4abca5bce9634cc96b98fda7434c4428fd84a3a1b0b56551c4e6e1d549f44d64abcfff").into(), + hex!("a5cbee883c7aeeb2faaf9ece2f2619d2586c95862cca694edec565a440be0a91e0655b172b9cf23c7c949b1d7c015b11").into(), + hex!("92158e73fcf8486c92e84d0d2ecb093698354764d421280eeae8ac0371049f490d6f21daeb3581a8a0a7a0e01d8b430c").into(), + hex!("a2e4d6430813aac19cfab8e48a7ad09f35be25b12fc73b47e8afda8e711356b825dc54887ea43a49bba7fb6eea992349").into(), + hex!("8305e4f678a14d6f2e2ddb55bfb411591792c973093369965313bb103608802a455c5cee359a9f21fa88d34bd4c3b979").into(), + hex!("b8632f75d2c2c5cad531a85ca7488c14ca9159a2ec6f619e1e09441adc0984407e8e2b63227a989d704ef5f5e51befd3").into(), + hex!("a313c4b427df1a86727265386c031c25489140846b7a98dd6a43bb519094c9b103a61713f9a836d091b26e95c9b8f34b").into(), + hex!("9107bd3f48ae28afbb692410f542ed2ba7b345a112e0f99e2a623d5ec1683e151c342b5e0c4c69f0f783c66212beaeac").into(), + hex!("8cfce7c9fdf489170fd783fa96e756bf8da427896da8ab57a198185f9473410ef408397f5b153702fcac98ad13a79c89").into(), + hex!("91a374c9a89b97ddd2b2666b6f6add414c7b799581052ff2e0fb6bb1f1b15227ec20d05ec3db7d70f46c4afd11a08cbc").into(), + hex!("b881b33a7cdef8b4faba7f25a04e0ab2a84c8f9bfcffd0998782922299b00d6467114781d73bacf7ad6d38c9b8d636c0").into(), + hex!("829dab2bdf70dbab8b0fbf2664eb6bc43c151d307b8c092f2cf6416dd7bd69c6f02d0aa2a4072834285f324f5a1b1604").into(), + hex!("9829095444c183132b059816603072bd5bf0cd0d8de86275a18696524efca7545ca1ba126326d4a8ceec119afd026773").into(), + hex!("a1494721032bd0bd5c2505b201b453d9445bb9dfe07111c15204353cbf6e19b960950421f36df3b84ddb1a5ee4bdc78d").into(), + hex!("ac625c1f77b218ee3bfc872261827650d7814808ae91d6f84592c8d8febbe1df5dbad667f45c19667aac0b00c3d03c00").into(), + hex!("8af162cb7276dff6484d3c8b3ec69737e7cd20c1b501bcc5fdcc1d673aa9c33ea5fa56b7a37d85e3fed867af38d2b5b6").into(), + hex!("86481478b9c71d5e2189b0f8757932dccc468925f0ff3bbcfab37616e04dff078234fa5eb6c62607ba8040149bfab5d6").into(), + hex!("8671cac3b7f614370032e63dc16cf0fc6b8c43d1bc203c6bc270eac3385f71e9cbdacec90f09f118471a5a7ae9670291").into(), + hex!("8c29132235cb85ec64214f462b3d18acac3df4eed105cb460e40288cca062972e5d62098dd72f78e042a3c8a268721d6").into(), + hex!("aa177cc113ba661e52f018ff1b3846acd095c90c3f64cce30eedca5e3f6660da38e3a8097364ec8177e55fc8f5456e8a").into(), + hex!("8854d76a334375623169a816e2bb8f14d468ffd4bb771585fec42227740e05bd09be4fb286539f7e705f9c98d15ae0dc").into(), + hex!("a6e802c4c38ee34d875ae4ad9f38c7fa554b7e16ab0222071bd06ab50d3acb09fdb179f7f161d8f8f80c2fddda28b429").into(), + hex!("b518386447c773775ec9ecf557b01a077979afa57966c1b4c3e54bedaf18a1ff8861aecb561347ea6d9f6032935a6ff7").into(), + hex!("a684bdd2c75bd21e066e7df1cd7e7d768b211f400ca710eb6aa5c1b575e0782d7d91a6af01720913386d78de0847b3a1").into(), + hex!("b655c0e136e83695f0b25d31b49af0159c2f9aa1fcd4ad934927de99599700d2ea768ab62b616585df5cdece6f46badf").into(), + hex!("a99d071bf965760a9a4d557b16013703a4e683dd38074fd4493e4c126b8af6f6220bb1661087722ff2f421ddc024ecc5").into(), + hex!("b5d51947147917a1912064eca5f74be7c74d62ade562ab60d354b1fd01fba1b75b91b82f2cc127cfe4fdcc040a7f4473").into(), + hex!("b02b9f32d577b105dc8b6f36a804d271793c2dfa0d8a66b8f0d97e95020892def80394c1d242ef8abf17024853ec444a").into(), + hex!("96147cadf251a2879bbe5510a1ccf5d390d786970e930c244f769ace17c226244bf3c56c484de850597156e938346b67").into(), + hex!("a1f646de8238aea841757f629b3daa1c47ad54b4058459738930351ba2ddf39a2b9ad841233b1de3e88a69135e180b96").into(), + hex!("b02b5260032a87244e9987e9f51f2ea3571ff4d585d07d562fb3250a5513d35891e8b64bf628a15465e5b558af3211e4").into(), + hex!("b727d9365318dd924d437140b3bbf61374c9e19ddb666a5bac3ce231e3b7269911d27b7456a5476c61ffccd334e3d2d8").into(), + hex!("a15d6635984daf78974cf8ef80ca0a2d02030363b52c69e516841160c976f758e3b933c80757edbaaeb0a804fa0afdbc").into(), + hex!("891648e5e8809c4c66b3c2e75eda5f054d7a0127e7f71e155b45521b36745581b1843572a00eba7e7002c2dc04076516").into(), + hex!("a2f9d4e689c34dfeff4a7a1a9b23cdc90b2a798186deb4a37f7286895cae5c7fda3b13f86d5d70322e5a0596818156db").into(), + hex!("b45024f4210cfd75b21581207548ba98d00b5cf0e18627060623c5802c6d7a66c2697b439eacda857e7be9debb0657ca").into(), + hex!("8d5a72172783ba9d210447c45af1b225a920af6e9d78e8ed37e82b606cdd63c5c795c9585df1aeb3718d204fff13c190").into(), + hex!("a2452643f54269b1c6eb0d667212952b4aac4c40e82041bc6e8ec6ddfaa688ab84bb256612aa7f22e5bb1d141820fe94").into(), + hex!("acaf20c8193489b90d3be918d07aece660439496802a9fec182d06cd208ad15e1f67b3ac629d808fbc71d5ef864f43e6").into(), + hex!("986715822366e63c053f215bd488779d678cba66c5d88c9a6a2efbb5cfa65939056a4abc8e42286682c61eab3252facd").into(), + hex!("b4c9cdcdae9ef10855f55bc56a36bda3d76f075fe1a1be1d0d258aec65a4556d458dbc703978e576405ae379522d92bd").into(), + hex!("9911734d43686def7a16eb43d96e84f6c64af8b66034668236acf1936e3ee12b7b8591df1d6dd8933d84e6fbbba701da").into(), + hex!("b0a0cc81cd4076ebb83a2b47e00f050c9b86da31bfdf6174f274e1c32f64af37a94f0434f47c7aa54835ae7cf48ba46d").into(), + hex!("99de7e2c4666d71d3fd26b83f689fedd6ab16895366382ce36c70175b49af7d85d922b37e034e15dbc794a684b7d041c").into(), + hex!("b5c575a5291202d7479f2be81ab206c5a2e1d3d9c5b6b40962b02582c9fa33350498e611b4c1ecbe1182862920ae27e0").into(), + hex!("b7a4d0d1a636bd4b897d91e5ebd51e1dec470d4b7db388e6c87ae7d4066bac883e05ee3a5f81eb0b6406d1a5fc1bd54b").into(), + hex!("841407e7644a789deb8d799c18e3060869b1ec1c1baadbe2033bf37e051209b07484486cfc604f89434ad2fd19f0d39e").into(), + hex!("aac8b5be9205d1e0722fcf6502a0f30d8a35d077a7d58da4a926dcf74315c6c27b189aff0cb1310a5cb37d54d57cdf66").into(), + hex!("a0bc3e9851d64d9cd1330bf3b6d0e0bd22b825db2816821e7cc41d91e88546c74a0cbdb7eeb17a07a551a96609339ec2").into(), + hex!("b2d424629ffc924f0f439cc4064398679130da9ed43bb7f16996cb8f7f7a536201dee588daa78a3afba881e37fc8fbd4").into(), + hex!("96f7be30866339b81bf07692efb4491090e837d0d3357fc841242780eccd005b268c7bc98d0fb1f802892f9af4e5ac05").into(), + hex!("a4357e723bbd5e56418856a791b11107952cde3e4c7d46a9b241088caae98cf64e42bc93dedc67dd0eca2d70408dd0de").into(), + hex!("a5e02479ed5d2f2477fccddf56f3805653d60821bf1d163e707be1c158a39a933ff76d5800fe169a73b580563b52ebf3").into(), + hex!("8d55812230e112daa8ecb97226957798b7bb6111f91f4d80f2215d63910107f37d2b1ebe92ef58cfe3cced8c76b64e3d").into(), + hex!("a6eb94bea9f1b28ec853e4c74c72031cec40aa01a9a70c73981e2c62960bd2359568a7c6d464d2b10e71c054add70442").into(), + hex!("8804cd0c52b7f7d04c17d109cb3168c5939fa6386bbd178a8ac3e67d43420d8d57779e6a0a982e42cd9ee7763c9afb2e").into(), + hex!("9116ed61e6414f3f6910a9ded17f803fa4cf97c098eaf88536f77ab281be5518b32b09c31627d61c6e9d3cf127324bde").into(), + hex!("b9c7261302d385753a6a7ce32365ac3a1c51ab60a7a4a6d5c63aade9510e759e16f5b23e35e7e8ed8f1dc28d7d3580e9").into(), + hex!("af7bc0b6e87238b9920f8af38c76a156317c4cf0ff2a2ca8861818975c5d8b7fee8ab7f843cae182341843a8a7cadc0b").into(), + hex!("94cae11811062358ec48ced4df56f88f3e1bb0eea296307f53e73de79b9ce48a06cb3d76eb4c152052e7b3420bff5bc3").into(), + hex!("82a4f36d5865d85ed89568c2ad190d6d2b252e8b83595de881f970a69c8baa42b1b5601182bb70a8b2fc284677210e02").into(), + hex!("8f3d70694fe5e86e94f6b7e59cdc5d3ccab8e41181bbeaa7f7321318df278ad7e85611faa8a5a4afb599cd67ffc681d4").into(), + hex!("81986385f4bc07e775733c3e79a5d9625a7dc4831a23b390ec65dc91482d4f58f84463f260ac292d4525514918c8ff4c").into(), + hex!("ad054427eae1a29bb6565039b1f23ed4810344819cb847aacd2638761cc3a0246bf4069b660636785c7d51dbc19c7786").into(), + hex!("8fa62b485e3be46ee107b5f7748373abaca5ba24d2c60df2f9fa0f12946828278ee93d5ae236d5f3c9e046b1d9a29041").into(), + hex!("ae43cfd328bd6620ad0945739b561e120cdf00801e51103fab8de7887b4cf037ef63fe431a349588f7f8ff8f7171e193").into(), + hex!("8741c7b1315ce083cae37e797b115c6bfae09a0802963c05e4d141f4d3bc1b5cfc4df371ea070db40382518b5cbc64f1").into(), + hex!("b4214516b6151a9ea215443dd4ae4f615d994d766449eebf94dddfb4af3cf6ce47ac81375711c51b2b0559d44cde7640").into(), + hex!("b74ed4f8f673ba4a69ca8481d70ab1e672bbec5244f0be2788344671971d4ddfae33e6edc272760c5db5059abd887c91").into(), + hex!("acb93a3a3f8f24adaa99e46d60d1751e8a3befaaf73f0276ce1637fad745e8f572b68c09f004839e5e2695e1322c099a").into(), + hex!("8411e66cd8bccde3f58628cf4c9bbfa1114a3cc4111ba29c7fa566b759914267da36728409c779a4f5bf9da97efabc16").into(), + hex!("ab2e9690ef0c629a72286f9a7238cc15e71bbb672fc8fb4571cf268db533b6aa4ee70ca6056219002807695b85611f38").into(), + hex!("a8afb9df00edcce86c3d3408df5bfb01ecba0e7bbbf7c263518d72d883b938c8c6aa9f13dcde7e947ff29e93fecda44a").into(), + hex!("af295fe64ff53f14c49e79d15fc0337a50bc6f41d64925922a5948b280d5a201930d34be85a37e48bd49fc3b6382166f").into(), + hex!("8e5f887457b984cadfa3c80b36f755678cf3cf304529efc082dd6e48c908366df5dce3966d799b22d824ee998c3d4e88").into(), + hex!("b110ba5e5bec088c799964030b83fd61fb6f03e9e96e959ad3ecea5bb51696d7717c3bb20e82c4d8940c63e1fc118198").into(), + hex!("aa4b560a8fd436438ca6f40414b600e796ff4af5fe67860bc525c9d6fad0eac34d7b4ea94c3c1b4b80b0964619cd7e73").into(), + hex!("a4bd8ef6966b6cd42e3a50f2c86eb470675dfc402b0d1e4ef4f320330272d8fb4461865f53c62b7e84baa06f382f1723").into(), + hex!("b378357d1f359b4bac7fc3e3fcbfff5c3877ecbcdf5209e177210fd1ee5f2b2f4a24a7c28c46bd4a92a59d5178d8f78d").into(), + hex!("a6f4aaed1cf96dec8a96aa929bcc1ec1058d6d3d90ba578dfd8f77885829fcdce1126baa2b71c2a7f424b62a52ff968f").into(), + hex!("b61ca20b04db1be042ac0a5a9a444040dd4d246eb44b439ff99e03e1388956a4fb7f840c67559cc3e8f46ddfe64e8264").into(), + hex!("a409eccecbec9e0c4d70a52321e826bbcf2350f53662f59ed30f16d5835e6355e6ebe2d64f113d1141352b4e28eb5542").into(), + hex!("989f0e2e1149446fdfb8e56925ce2379d58539caa579793f977a5500f0e4fd46ba5e4df79f3f66ddf8ae9636fdc3bf29").into(), + hex!("83078d01f5d1f7182e84923f7040d0aa9be10774e82f643b784ca18ed6bc53008221a3b26893c40718624b8296bc2c31").into(), + hex!("8fb57e40286d26ca24d1cdada6e53b2f4fcc463853f32d0e4b8650e03d0659659be9ef4e33d18e6b5c86e5aaabc78fa6").into(), + hex!("891ae79c9eddc336f8d624e0c91033ddfc196173888058a4a735d652cd42bd50dd40499416296b2bf6182e57e36b0431").into(), + hex!("af4aa583e26e51b90aa34b79ba12cea6e20342dd071892fb667b1304a65b2fda65bad5ffa102f69f0b6c086dcb542fa2").into(), + hex!("ab88a5c49c8a2df332299b23537569e093a9c5bd39a8a20178efa1fafee00f268c1e8aeae92b88813abdc6141b116d1e").into(), + hex!("811f4c61c17f957d2bab89d221310cebe4192b37d4d88bfe607f5346069c43219e4e457c37fd04f61af68e966955c377").into(), + hex!("854dc24fab27b508b9ba8010aed2b9c19229ce35551d7eb769a684b2fcdbb6252fb6e915fab3fa03403438eca4f8cfd2").into(), + hex!("a0c2a2f398b4e48aec7d8567b3e5e32a75d22204f9d0198f11e2ecdf4c16ba40a60bf8398a83a56b193f67f4ab310047").into(), + hex!("b910317cc51e937f44bbb28e183665ce18f5e0f86181a50573cd9b4443049f2930b9296ee6fc2070de9f099ad605629e").into(), + hex!("b8f69e7454f6c539153d09bb521fb53acdeabf6dcbb659b1d6dbed4ff7c7fc31e0ab446e90107559e1f143973799ea1e").into(), + hex!("b0f956cd74ca22d0c7a9cad3ce4f1bbbf4dd9095a4e600315dd4aa3a30ad27f52570d6fb0d3cd9af6e85603c33a49a34").into(), + hex!("8efa2f96481ff3dae438a3d70621d633f174f2278b305e7a665390dcadd7d2b4dccd61b76dcd11bd30141e9885c051f4").into(), + hex!("8f3d4387acf587499134c6e8bd53b362fe1c2adff91508b74d02435a2046a2d3d1dd8039af164782df6523466c6459b0").into(), + hex!("836bd4f5a4e43f6578bb6cb48c4f7e52cf322c0e4a7de90fc598373cc5710b704375ad8837ec4e0b341fa53b732f441f").into(), + hex!("a2e000c7d1a260c710763ec7e042863dfea5166b82105e68de6b803d9d42d66627c9ac8a9c0689cc9adce16d287871fd").into(), + hex!("81585771a755b837242f20d8d59403222d71c0dc0e2bcee0185163196de15fbda13e60d4f6b6cc3c5fda00ff78b360a0").into(), + hex!("8e1c773042e3211d04f8c7462dff68f28c2275ac91d710d79d3d14d9db5a5ccdcca70199bb0e5bbd6a9b0de03209adff").into(), + hex!("8a3bcc0179c41135070536b5619f1f6eb88a27f00e906cc910942d9daf43051293329672373472c1a0bc13ae05ed736c").into(), + hex!("b83803b88db3f91fbcf0bd3ca692521a2c857ce54f1646940c8613cfa4387425e4e5e70d3ea473369ac23442b1ed6c48").into(), + hex!("a90d549a2909e27a096d97d33215c95ab5c0ae262c34bd8920417f6931e01bcfc84142b1ad25d55cb209271e0ea9fb79").into(), + hex!("adb3427e01d4e8ec3933999134e040053bd01c1d9ca26ef37427a55c84dc0466e89c168bdfcbfbb9fa144128046b5c64").into(), + hex!("b96007c6aa107be9cabc8dcf829c3c74740b77b3b5d7edba52f64983707aa53a657ff02b7c0e9cb8c7691243a60a426d").into(), + hex!("a17b3a41cdbc0be24ea196d38f84256405f99b95e854711aed7d881a839572700e6b4bca4f30c3b49f0be1225c1b179a").into(), + hex!("aa681b54511d74a8cd329366d6aa1fe0f11430a67a78caaa5ef0412545605a20410f5a6bc0584c5f0b7800f70a0f3d9b").into(), + hex!("88eeefc92801cf2397f5d47599838f86c0ce93ef2135398e0522e925e6b7fe2a67230c843be55a8753d243a0804254d9").into(), + hex!("86c058c53ce30d8c62ec83c3ad53e186131f7ab0bba1b349a191347fd5b70347d74457ab0e6586b14eb9b81bcf76b501").into(), + hex!("a42578e963df1cabbb45613d430490c8c4f7f940f8647df024796d2929cc706f0c6395bf2b4bc93af16fb5a1f2e2ce21").into(), + hex!("b4dfd1c4243616dd7fb4ff7c80e7a544c48cb2a17b8b63b90a3f279926c5af76f790cc1d6fcfefab15841572cd431b54").into(), + hex!("97dcf5d73bc42a52571b5bb8a0414a7d02bb9fba012122095752340a949d99d3a3a060104d1ab8ae532c7764a4f3d3fe").into(), + hex!("af5cb5a0250b4106c88503f3fc3b48002cacacd1c504c84bec5d3e6478a07bdf29ee6d009d7affc01b66d5aa138c8579").into(), + hex!("b02597748ae10ad7e5d3bf41e263093090736fd0305bb3f1d1454ecd3c796bc443ac9284bc038c386b5df72b45ec5df3").into(), + hex!("a60d817900e9c246a76d30f9f9f010be77f6e34361916a1af8d26533c26670d91ae5b4fa4e5f8d20ef50a0417f4bfa8f").into(), + hex!("b514b109d957db80470fa5a8dc7302a77399efda13e9da4648ad48962f450e4c51a88913c473341b2375ad8faa3ea8de").into(), + hex!("b2d59a1a4612f90ec1923169d16373df81c3a78ac416d3b0b3d122f9448a0f2ef4903b55557681c8c7820d9f4bf1bf67").into(), + hex!("a9660ffbe5d15e6c4695b666436f90daf19f5eaf6f74cbfdc9fc597b5e38ada095bf38d46f952c7f2b86afd5acd148f6").into(), + hex!("b3d5036a48c38573ca21b20ad21c9d5e8a23c512b2372e106a4e831a3a9f11fe98715ca3586af32d5aa9686d61329c22").into(), + hex!("b05b92a7fe1fd82fdf7f1efbf9eec4d703a1175c6fe3ca65569db56d81309ebf64aae088f60e5b95faa201ab42ed2c61").into(), + hex!("a01e73cd18a7971ce6735215a4f2a413a7f38dfa3584a091c2f0760c15d1ff9acb108716c93c7e39e228a164033976c1").into(), + hex!("b47e29c2b466d493760c885ee7df442bb62dcf39cf2014a01034dce5ecc827bb2816fc862e12b5abbee3394fb8854653").into(), + hex!("969c6631c4dd75c9f0af723d8c50d597fbe89f9b89e3fef0e77ce661bd7736fb3836b1c76c1b9c2b2768db5bf0cdd3ed").into(), + hex!("89721c673c1df509446c1f6437ded01437579e797986969bdad9d6da941b2329985fb06560df90686c763ec9afa77c71").into(), + hex!("a4c238a302c65fd75ebdb2a381f93c756e9fbb8bb6c0185ee010a3f434b5f05d683abda4c79bb589d63b7b72b16d3a87").into(), + hex!("97b99218a45dd8450054c6296e1aa140f14c6ba3309bdaad2c1bc6787988957f09cb0c87e850cd05f52536d78c68df1e").into(), + hex!("b53e4edbd722ab5723df58f682f8f4ad06736f243b6d3d4d933b56cabeebb0ab931d46626d3e16c69dffa5a5ffea36fd").into(), + hex!("ab8d3c7ca7d925df6e808b4cd5510144bcaeea6f201e43cc17319ea520612a4aeb65a039b7f39918d2a0ed326aa7985b").into(), + hex!("ab17fa115c8cccd2f9694015fb5bba3bfa7c33cd4025e44d3163ed2dfa298326f75f9abdefa7e66eac91f90acef1bdf7").into(), + hex!("b2a465923762dcfe26a5216d4804c7168eb2361e9794632c632a412b28a18d8252592f94d3ff515daba924ce6a541b85").into(), + hex!("944e0d66cbc9f0d2c9c35f33700a13781fccbad0593336fd947c8788f86e55e48445aec622a26acf07331f4159056e7c").into(), + hex!("92e3cd37cacabd949bda55fde18a40f58f89d3723aeeb2eb539fe8cf2d5c11044a8b63c58df65772450dcf561367333f").into(), + hex!("8d132145516659e2a23cfabe7989217425f7fac4b748078749e90b0875a0de4a11cb5e68c4cd7aebcca3f5d74912fffb").into(), + hex!("a325a22c07984652b7774ecba8ddfe5ee3fefdb91bbe150588202b3119ae337449a2637a0d0fb239a2a35ed9e4b3edc6").into(), + hex!("9475f462166d0dbb31613c021921186b0360949773c8498ac8ab2b53a5e592d4d0b1f33305b3c0a481300fad4b459f31").into(), + hex!("b47978d384d84a07376c9e0fe68c5ea4462d46ad6f774265dc62f69fd35c575d243a87b4a7a288bb3d6414110e475ecb").into(), + hex!("86d28baca1dd68eaa3aaa92b50d851706dafcee9021528022860b6b8bcb8b88547d03afc85c9fe866b5bc692f2de5e21").into(), + hex!("a092b9b4c62894a1c02fa66d6eb41088fe95627994c3a83c8f8fd6a07ecaa2897cb753f0bf2d5598be647d2279a6b1b0").into(), + hex!("a0a7b20ac27413413544cd23bc970da68eea739f0e3180d4f736efd9571642d2ab0c72f086251c3d9317e6b2ea708745").into(), + hex!("aa30c27bb9c6db7dca55cac282fffa625a570cb0f3aebeba824eea41b5d02d056dee645ff8e3510746a55d51a65efba9").into(), + hex!("b0fcdecd437e69b6c8e2d0c9f3aa8c754d35aa62c342de3d030f6d6080816261ea8c69b1f0f6123cd6feae78e2a7840f").into(), + hex!("a740611fd2393c66bbf6e671d5cab203d41c906388578a62c4f1bc2fbe63a4161c11394218a312737c1df23e573803ef").into(), + hex!("8ae82d8429a125c8a297cb4a049708ebc5886be12d8baaf8b9152f99c15dbfca9bf443a0e034d0eec72837e6579bcad2").into(), + hex!("b3312bedff432b1db8e78956400decf0de9a49db58f220a8f113f43c8e105dbcba9a5ab08c8d9cba50bc487406162732").into(), + hex!("98ce80c75d4404f67b91f2cb21d37d979e9881d173062d9f4944120c9105ec5a94e07b372f998b4faa8ae34508e47ccc").into(), + hex!("b53225a285057c4a3c8a9d4329cd8d086d7574db4981e513795a92c1c3f492b0f0b36bb98967d368d8f9f1a70f2e9e93").into(), + hex!("b1a086ea86bfdbbd242b23d9c8f29220465fda37442f06eb96552572676cc1b849411cbf207b8c279017ce01637a68fa").into(), + hex!("b211ea202d728b85b6c1f7f5c69b54c8b5f109422450562b0a77f3fde4bf7d56586971dd8dd3b63e211c1056c7f56c0a").into(), + hex!("a2abb29b9cc096fd4cc332c7a8b6dc84f0a21068a4190bdd6a72d52aafacd463c88ddb4f1bde3f597e08254a8c26f318").into(), + hex!("810b8abd26443c8e74ec0d0038720e09dde65a8f70afb696b7810d0c5577b29b17ff72e9f393ab64632e94c0113e5e71").into(), + hex!("a1e3b1630302e48fc8279bc0831cbb52673128dd44eb384b9812bfda6c730548cf825312fd42990d2ea731c520ab2afa").into(), + hex!("8d4dbab3ac64d32caf4c1de99375c38399ea83ce985cde8e2ca0686a91886fa3db7da025757a4c5394847e7bae0ac63a").into(), + hex!("8af3a0c287482ddd85e10d4101d59eb41ff87b956a4c3e0d40b67fafb87bdca1bcf9ea3e27839311acfbcbca079d30de").into(), + hex!("b981fbfc0fdbd3a1d1d46a88c24c679f0060d90299429ba8cb064f161e49121117f5b66f412c3c0b9217609a990d7d61").into(), + hex!("b3335b0a25218df23606047ddb14b99e815ab3f62bf3aa030704b4b07d5b34513b7cc9c417fd66a0085f45a6b191a5b9").into(), + hex!("ae1f197c17ffa4c4dfe26df7305e9fe74ef50ba2c06fa067518e8fd107f8417a9d26f8e60e88e6e4546ff2710434ba3c").into(), + hex!("8a9310197817aa1d4e417f10fbb2d020b33cc1f4f371fc80401616fac38bffd8c622e2e255626d82bfaec648762af9cb").into(), + hex!("85907d0ab7c55fe7b0632cac024bfc806bfbf25adbb74eedb5c29e534ce756fd448e9fd28e05293d687a7773e1410fc4").into(), + hex!("a1748759795830d9cca88e85197a1318c5d1056d3f340b53b14c400d3d0e2232409013c963d17dda520d48e5d150ccac").into(), + hex!("b686a253ec5b90503de67691f1e8be1e4f38bd457ef97ab2bb3f8afd73362856164c4a4a88b8362c99e249db22c6b704").into(), + hex!("b3aa2101137d4f818b0f9ca1e713c35e14869fa030542e95ed3772822d7ec5da82cd10d8ceee66498bc794b10d22f6e5").into(), + hex!("b6beda27458a1f9df1e4f71a6d9859941f49db7de76c955cd10783d7b995778a6ed7ccd196ed88106de43baf65362fc0").into(), + hex!("8b73433bff97ac9a75d9abf6dc3b45af7392838afe796622a4fb9460cc8b70f25baacb72b8010c804bfef86c475e91a9").into(), + hex!("98d5b096617421a9a67478966d47d6fc22cc2ed61dba80c2a18a85fc6dac9f270b317568c242a38fa9da1e3d86a97e91").into(), + hex!("995abae437031af7baf568994080208793be0d17846be80c450db80bc5b4eafc7ebb86fe06e88c8c742284264164e412").into(), + hex!("b552b8b81a3db53569d54b2f0943c7a424556e975c52121eae3bd53fb29a4f21d4d66f322dc0e39a347fecde537726ec").into(), + hex!("802d558d0f099a59b6b7d41884127a17532e7ec2210c57343622cfb01e50a49c5ae4966a539ce396cd4be9d053c45e9b").into(), + hex!("b2a8d65e7d587aa88c231cbe9eeb73c682355d2ea8db5b94a88e752c5f5d526612d38653d45a13f30da0156ae1e5601b").into(), + hex!("a0adfb22ff0bb5f825a48535e87bda0e08908edd027c721454ce487776dc3d737fd3bda8eb1c869d0c1e4369518add4a").into(), + hex!("a7d0abc4ff342b47fad9fd3cfd3c6beeb6be27c02cd732980a31cd82bff0e7f9804725b3109856c09245ebdc263cf5e6").into(), + hex!("a323b68ff7febe078f63c195ae777115333e2d2bb7087cc7c39859eaa6ab0f884f275ef1194c1bd2c90920cc815e4fa2").into(), + hex!("9854d35728578249a7f6c7513e71f5115135105e2549ee964633c758bf8f57fa9c893d8a01664ca9496856ccfc59bab8").into(), + hex!("994f670faa3ed5b4768a2c70f21f6232148bbfd68fccc837b93e280eb4285a93a062a4b978b2c2a74803989a373f1d0e").into(), + hex!("8be6ee31cbd64546085f377277354345024af6e7d197acbec766de63496107882842754a4503041aa7898982c1df35b9").into(), + hex!("8c2087b38a1bc17d667caf5fa082d9b11f4f939ee2d92100aef4203fa255c1e7be3dbf421fc58e794e78bc58bafd4ca2").into(), + hex!("836dbc57adfe226490c6b1405f3ecfc0dce1e8cc4e527e173a3744a7c6829fc63ab4a4b30a607744129de9fdab44e487").into(), + hex!("b6cbbee960be11bb589a5ff5d3396f722e686bac49609415a14b087d9df17d4d3578c73e4a2f02e32c99c8387a539ee6").into(), + hex!("a8bfcca865d5cf73e3924c2c58879b624c3c922b7762aad3306eafff2f3c5379a07343de8a89f003a62c06930fe02915").into(), + hex!("b125ba40e3524b2cd042021587f81575860e97918ca0efed51bcb73cb4f5001f381d9a862bc03cd9760de74f047fa893").into(), + hex!("8fea473a4dad36ede537b5460546b7de351a3f0f9857da9f515f737c91de705f05b173f5bc7c0aa57b92bc425e8fe498").into(), + hex!("a054afba52811e3e3874b105d5c58cc32d90e947332409e36d2649819a5f7f6cf4358a7fec4efa431d2b79f7f8b633cf").into(), + hex!("8828e330c37a53cbae125476fe4f60d0ab91d79b9580e7e398eaca3a48398d9d8b10440be29ff1d0c0767724e7e75f10").into(), + hex!("b14982c027aaa25ac1442617afc1ff8f8fccd7ee45aa8f7399b6c209fb5a31024be8c3d382db441ad73933a4a220b783").into(), + hex!("b756a35b58b0192aaff1fa9d275717473cace1a3e68ffba0b966da0661ee42c6040dba48061a1bbc7d8d35bca0e8b02a").into(), + hex!("b079f8de8ca654ae9e961a4ed809d66e3404025251b0eb814031e0e525be3d4fbfa8d8c6bddd2530b6cce421c78af869").into(), + hex!("8b1ca9733a3646b6437771b73d76e8cf972d001bd1b95564b8bfc78abe1f0c9582c06783bf1aeb5c1e0d2b263d28ae4d").into(), + hex!("8101f7f34107e5e7619c4eb07b8d6b566d775064a42ab6c7cc8f99a602c0f33bfbde23dcfa2bc347dc954cda180dfdd9").into(), + hex!("88a16ed7ec1d78568532b4d3050c45e0016d9d1b896e9b29db6cbe2d976dc9498cacb7326186567f621defb9c4ed3ad0").into(), + hex!("8f107cec3acce6ad6639ba9d6f85ecfe2fc59c03fd0570e28d8b4d5057ab1d0ea98230ea57fe748c5320a59d24b876f3").into(), + hex!("a17c8ea7acd0a6912e9f0bf36838d344e981c3e9851ae410c4f41247de843a7caf67d6cc1265d21f478b93f3cca47732").into(), + hex!("a109789f1b3ee6adada0c65f4ae65e141c21751ad1881ee347de052f5cafe38c92393cd63f921e9bbea8b6498c406478").into(), + hex!("905a7d87fbdd0a3236fb9be13492ae969086d49107a294333497a421078634b439737523aea98daa99bcf4c4eb0f8cbc").into(), + hex!("96a8d6525a005cbd569290c428514eb9f3968b54d05b7d41c6c48f845a71fbfac9628b31291a90f36608318096fd2f62").into(), + hex!("acc004a7263b159be570092d65ecedcf15cb40eb5e26a57e0584fb65526db224dae39c83249fe6b18fcdc1361569e48b").into(), + hex!("870ccaa2f3470273a4ac8a7f905bf17eeddb07f901d9038b324e419dcf3e9932541a90d310670939287d79a9348db44f").into(), + hex!("b9a9a8b1a91627d5b4672f76308cfc8455310e591c88b3d638ba962a939efa9d012a7a1fa4c421202b8ce73469c77aad").into(), + hex!("aec66e24360f7a7896ce11c59aedcabf4902665d7accc491dfcce7447005fa8d91c1342f313a247cd5f7a9b1da26006f").into(), + hex!("92d9a5109e3374d39ed9acb33940b512d585165c3cfc263e0b752449b8d7ad54c6c23a568a95395a830e4b9c1e9439e3").into(), + hex!("a7eace55e77cb408c04bbea17de1396273ca7246f2e4337e153aaa97d9a86f284804ac6b4da65e0126e9746211e74481").into(), + hex!("8fd6c6d8a117c9502f8cd89d90b467530129fdaf4bc2d1b4268a8fde38ed34163a07f9d276808e891f45e6378ace71a9").into(), + hex!("9832534918b8012afb4938d6731e8523f0edf7fab4ad37cc80860650c0b5a30438f7fbc4646fdf783955adff8afd1ce6").into(), + hex!("b03dd3044da51f68297b66c235a9d20030435991311e4d2e198f829975e57bead517eb0084abef957f1bbc23b31b5d7a").into(), + hex!("ad3ceb2a51b83b22662106fdc8afd3ad944357dd67016ceae679b924bcbcc012c4d689316197542fabe3f2eaef2d7a46").into(), + hex!("a5de9885202b2a87f83667d8225d24e0451d845189ee9468f6d5ff78b88efbe5b395a2fc305ca97e46affee7478c5e8d").into(), + hex!("864aec16a9b6b3b233826763b4495151bc0eb8c18c64ce159fc1230806db1c40338b40279106f5ef21d9fbaeacedf062").into(), + hex!("92f01f06fbdc8d6247678d980e09808496616ad77d8bce6df8d0efc7e9067bb9877be71c150cc9e291a1377ee2c14fb8").into(), + hex!("89bf1e4c2e20c338f37fcdb6d9e38dd81196fb09f7a9af3787efb634e4aa2f5d84d554afb04ba2b00917d8248b42faae").into(), + hex!("a722feb58dfc39bb6e8179ba31d2d73951fdd2f1e68cfb6b5557bde830073c5ee44864afc46fa3401892423cd1e68af1").into(), + hex!("8e5fc42f39327d08a611f261292a59c48e0eb3e3aaaf7b7eb0b5aadecae7a83368dfbb9ef2927e894d176d43ed4748a5").into(), + hex!("8f35ff0f33b39eccf0b89b067c45cc74891e543d6d7c638902f87c024f80d067d63c89e71f4534c1b7c65d0c38d57640").into(), + hex!("a9845686d040199cc9531712cb5f414c0994c49ae13d2396f47c77722abd0fd0f7f5472d3c9e1954e46ec0a5098466cc").into(), + hex!("809f958058059a2e4bf48c75e0bd803e6229952b1f3ff1dab4c7e8fe214a89db2be5bbec91c2e2d5593fe611201b3dc2").into(), + hex!("86d6f344f58561e65497c051ebe45b8a34445f27e247997801b3dd06f6c4cc6a073ffa87c6cf18384b20e81ff5fefcce").into(), + hex!("8be54b75445f775a883961c5aaaf33d050475cf9e6431f555f4469e3d2601c6ae289ba1c7e731b975578527b8958d083").into(), + hex!("8cb7bab37076b29f4588184e25032bbb75cd9298ef6fa275f9744ac2ec8e87cad57acd12e834d1905e06600c1e12c6be").into(), + hex!("b64db39b8e495b81ddf23fd87cf8cf2a86c55251c7afceb4d4a453193b471ace924fc3948b0d1984c57ef9d7aae39306").into(), + hex!("ae117215e0ee7cb7d989d65e3d3e6896205e082549809478cc71b47cf8223f70a414e8cf8a88fa9816fa766681004876").into(), + hex!("b5fb0fc564054c13eedb0ccd27801aed67017298979e2e28153a6374318277c1c0eeb9909a8601a2109f003c39f9b8b5").into(), + hex!("acd3f514f69f25ef2cb8fe6c204a01465d7adf7bcc7051a186f7c226bdfcc52530653557e33e7bce3e3b4de6de84eb32").into(), + hex!("afeef3ae99f88ac3b6dee086573281795391a116ab36b6b27406ac7cfe1d3d19f0053043b304681f22c948309fee9e9d").into(), + hex!("80b4e32dda024486e0d4d3951a1adb4485b6a668787adf7bb87f0c1e43b1e0db9d93874cb3ec20a2bd6d09af7b007a86").into(), + hex!("b3ded6f1cb567d72ede753c26e29b94157715ae260625bf6b2f77446212225d588d8090e80aa0a7c250730b37071e123").into(), + hex!("80c56856ee9030ccd8f6b85fa5791da52292371d8ea329939b8279dbbc21028e112a720e1a2889cb256b0aa61fcdd374").into(), + hex!("a303b5e8f7b95b3f3007aa2545ec68554ccd9bc213334b294ab765b0a59cee0665fab36362d2b85ceef43af4fadeb4d9").into(), + hex!("a5138a976bb15460a4a3c7d59e3b27934481a1b3836f105809916f5f675219e384349315b1634948d38fa155439029e0").into(), + hex!("96ad43376b53aa6ddb5ab36e7dd61c160796633583bbe7bd6fb1c0ce129c1a0a3838401d65bcc3887b314b22a657d948").into(), + hex!("8bbd96d5d90d5af61ac0bee16122fadf9fbaa372ed67352ed5727758374dc3dc1fac2058ff84a0160b414546400b3107").into(), + hex!("b33aedf71c73850d104725ac554192e08d7dd435c65f7032e86f226a000e5d56272b54abc5256da903739ed75403f141").into(), + hex!("ad91beb158875a267a2a947fa7311549f55123345022e6c08ad270df9036085f56ca9c5094ae02aa3a6a34386d57e864").into(), + hex!("83a8cbbdfa04092d840b365d31b21b8bac4f6145fa52cdc05557dd8787a0065075e3c23a25fe5b26daf7ec6ff4e968a0").into(), + hex!("8ca0d230100b64a83ea7f739f9caa1509832ff784384a2740d5c559fb4117d4c6d088dbaaaaf6a6d575885da9a951e5b").into(), + hex!("8195bf856a42be4bcbaa42617f235bfc5294426840903d25c3d306fe2547b5466dff350610ede21d33dfedb2519f156e").into(), + hex!("9350f68790cabeed94920a12ab40fb4d2b68ae64324c1c3f1a00fb6d7572e8a5f29a4c14a0fcc7538d172c55162c8aa1").into(), + hex!("961dfb7ec2f7b7167bbd986dc608a6fc4e2c6d74c061a24bba88b7b32c5dc587f413d519657c38753aafd37c3d3563f2").into(), + hex!("82f9921d7d3d2a62f5c1f87452f2bd1a6e8ae096371105a5d1bdf6034cd401395e9b325715c9215594fc12c01e8517d6").into(), + hex!("b49032e9b7a6efb300363213a81a1b5ad4b7dd005179b53ba7048d29a7dd10d1dabe7fbd9795ea8c30f8f279c7d0510a").into(), + hex!("995d383ce5720be7c44c020f1f06c3b3ed07236684a25d915070b77d6038ee43535218a30d27b57055757b44bc578e99").into(), + hex!("a94271d1886b1ddc984a0c38efa6e3d97c75b479018a00e3474e67fdb0def1970ed3ed232d6ba56a1baf163461669646").into(), + hex!("acbbfa5136ce5d83a569734dfe3a0f55b4c90362454eaecc5cd37f39b5e4102830d77557e75b641554a7aa90c686f34e").into(), + hex!("80d0bb10037029f0d8f8c9b9b46f0d0ff32b2198af44a4f84c8c0ace60f2b39f8f8d284308769c6075e9425d6229905b").into(), + hex!("ad7ebb0b1b2964a3b3caa90150e800364052bb464888ca1cd08dc7c934bc0ff8cd2a7adc1d81b5258f9dd2be3e2ee126").into(), + hex!("aba82261e600c4d1b4719a3dbfdf0df30017251688f2326e7e43a592be4e344b8cafaa2c8095d0e3063534eec757d82d").into(), + hex!("8ec48f531682cf43e48ed7c4dbf7e04915e5e217c0dd0917e20ac9ba63a4189e59fb31f75bb8eea025b8603403fb07f9").into(), + hex!("aa9c37deb3ed7f08eebd15adc8ccd36d3a3f0b851e6cc1a444c328f330d280dc76f1f56ce126f0c4304389cf4b7b0eab").into(), + hex!("b8567a2f8cd6f0ecba403aa7fb35af29941b59c531828d42fbfd0042c90292e31d308761bb4b5aaaa010514cc77d5546").into(), + hex!("8dae4dd9acb7322c3e50e4a8116799e0e88f83affad1da575d0b243c73938c8199138e507d35664a51e0a6ceaa6e1c6b").into(), + hex!("9098dededd389466af4940eb6ef188e9270396e4992cfd53dffd891e8a96b739e80f8239f4ba649ed85a1bed7c01f856").into(), + hex!("a6d24d97b27738bc8a37d4c9827ec79e17685bb3350d6cf7fc3b932f24bb379cae0db1fcb6d498fb1c279210d32fc1a9").into(), + hex!("97b81935b9662c139a747ec2a071ce48d2595953bc5aabdafd971a85e4cd88a04e57169abd895fd0716b5f1b1b7009ab").into(), + hex!("96a8df41518a2fb4c0a07243822399d09e6c1c88181c557e35aeba09ee91ff58c118acd96933bde7fdb26b2e11c375e5").into(), + hex!("a280ad0a14ce7503863aa922d0ba10a3737d6c396810a1b3b880ba7e6807f8a425f3b51f77e260bf436106f9514616ab").into(), + hex!("b601c5844f45b53b36cea122f0f9e23e8a6062798c045b34c6ec5e67acdd2be4f49c2774843a53eb1719150203a96f82").into(), + hex!("9941f0076c75a59349d7fe61ae188086913b810427d1a75a144bb1373954910f07da95adc2a475f0ab85767931ab0107").into(), + hex!("aab58f2af61e08c18b3e988e50d50b57228c80273db3373b8b2d2794d302d5c6b5994270a1884b6e627b2859c02bf5c3").into(), + hex!("8743d2ed2b45f0a5730667261ffdd0c705a6c3690d6fa1cdf8734805dd2b0c649cd7a51c3636f9e5b294139eef05ea54").into(), + hex!("8e73aac312ed5c986cfb54e29f2ce7d6ef5bab298a1734bf6a67d72b5e22d4fdc2aaf3b0139b3fe559d2687fa06773fe").into(), + hex!("8fa1238a436a73c16ff7628f26356a1e4c8431ec88ea1f19b64504b009d4189a2809a850d1095a724d6569b038d693de").into(), + hex!("894d24b00ede02cc3f78ff983e57097225693e875f3ff75c3defd5a7ed9f3d25ddcd537cdc580c04139c948081c4c15a").into(), + hex!("b3b515180ccb2652ed25a63c73d8bd8b02aadfc4d9d459e0fd8cd43a4f1470be0b4fd7636a3906e6b38619dfd0ecfa46").into(), + hex!("ae314b634d178e0b1dad8f95270053de5267b134fa53b9c8a8ba878335fc33e81f665ec9b7d40a0c7ddcbe30a38cb65e").into(), + hex!("8b3e812daf59577e6727136deef5d2e57a1931f44c48d1d47c107cd7a9e2cb88d63ebb046c587aaa72ac1fe8702dc802").into(), + hex!("b8093bc71b1dc2296478c22c193cda187c27ffd0bcb9f6a91e41bcbd9f50ba02d52734a040ceace3db3b5fbbb6707a14").into(), + hex!("b2f3ee32649cca7b44f6bfe458338598fcf996fa84eea1d6a44688549f86abd19d1d75552322ec7a04b02beb31c10af1").into(), + hex!("b46c888359aa9c3ab0d62801372beaaa8937f23c5d9cac75b6e94be28e3c9b5765a7b88d6fd4b4d33630aa772dc55245").into(), + hex!("913018fa5bbe2e87dc1b32d370955ac8511a2c63786b6ecb8210adbebc1e627df005fccabd48fb2c18a32ca86f52d8d4").into(), + hex!("90ec23b4ff0899680c0b3e1d00d20bf5b4336dd2ba118cdb4d45950fd28bbeca8efbf3fd45a6903b9d2b95d00be4344a").into(), + hex!("871f36741675ee113577a93105ad336e2587eda8712f2c6a6f30c62b06f7f5b95a1900f64cf1ca449d68c4839b7cd5ce").into(), + hex!("b25a07e9782e71713f30cfb483f8bd2e6d21c4eca642c87c00874beaab7554ea86f2a5608b0eb6b8956f74ad3fb6a981").into(), + hex!("8b5a4f62746158140fecd73c4d16bc3510564e9b366df0fb34ab656413bf9aa9c9e4626d2c273729c78b0ba9c94960c4").into(), + hex!("97dd2908e63e4ad680a93eef50cf9fa79cad68edf2db11918b3fcb04fe7a9efcf9d882fa0853c217cacb413e32faf848").into(), + hex!("8fa64df5c9cce4d37dd10fcbc182982a75873c4142758d3aa78399b157aa6ca74986fcd2dd304e273eeca659ac622819").into(), + hex!("80ce8d0d7cead521a2214b198ee981d331da42bd9ed14e554cc8e3ce5857393779cc5e6de64cadfe0c24defc861bb103").into(), + hex!("aa3f4777295ddf3da7b0f2f344cd7296f4813802c61752e04f8ede8d2049bdf5fe02fdee6e0d488bb5f96d3aee952e3a").into(), + hex!("aaf21f60655eca3304b3053b4fc2123db3587e4a091ad229088256ccc398f443321c0258917419f301ab6c16c63232ef").into(), + hex!("89d7e1a77c77609de67110c47dae1baa79b67100274ee5b7234386681c657572caf14ca5f57efb0d484c0269580bd1a1").into(), + hex!("b8a2150f654afd7e9f2d186d327a6444bc8a7f65aef6476a9e5b588204d2ef4b904a4b8f76933509067b17a9de7a8726").into(), + hex!("863e10e84764fb383f63e8d8441e5a7746faa168bc51641d8fef6492c4be10bb1587ab4d529cb92a89980886c5d296bb").into(), + hex!("aafab1f438d1272fc98494aae8834f564233527fcd70b14fd643c1b66690385cb5357ddddf27e0a138ba5e9c2b930915").into(), + hex!("99d352a00a34d091d836e51d9c30c92f15001d24ae036715fccc40b37c2d704bef0126909447a0dbb51e0c34c23eb7b0").into(), + hex!("83e54312f86c0a5c7d002f2605ea9d914bff9f677d63c539aff5e71c039be0272da2e8ec4b2221ac11fe0328517094b5").into(), + hex!("9135b68f5f39b4bf3e262568584ac4c1920d12c60c6d1b78729431fa6e70a6642bb963399a80f35f5f513eeaac48ade4").into(), + hex!("b111a8b4cebf898af8ce43ea6a4dec1a02a9707d181b5343b1b2c2299c4619a7eaaf5222febd3a53b3c1fb049b4f7be7").into(), + hex!("b613d5f4911ae12d1a989aafecad0c346d59023c01e0159d44ff499b3d01350d7fa9e59fcc6f86e6942ab5c17dc5937f").into(), + hex!("887a90675b2e03032e9d99897add452f27e29fcd9aa406787de7d6990813a3ef2f68da7d3f4bb97d693e00539e625b92").into(), + hex!("8fb8ada4d0d840e491426ff423e618e9f970777ea4d9f5788ddaf395fdc6cf4959ad6e457a5b8117ae05e3287a500eee").into(), + hex!("b225ed3ffb4b67b9c8d229768c7e51f2e026e6d9752538e7990e543f583aba65e65fd04951cc93067ccb48087b06b6ff").into(), + hex!("a763ae8e7246403caacb94887782887f1706df6a2469916855971abc7e631a6f354c3cf161c0578217167760d6e45fef").into(), + hex!("99439451a9d2b41a1d3bd014de9d0f4f91104ca7676edae2a77ac8b551df3d535393c7d758dd35be71548d3476ebd3b5").into(), + hex!("80d4468cd18626ee23cdf490e62f8ae72211f03c7ba0f5acfe267f4f6412021ec251cc1fb6491ff7122e60b46dd8de7d").into(), + hex!("b11b2408b3c66b588091931ab6ed8e4e341ff92c400a6da502d26deffe60f50c508fd2700ad945a89e30897a1c9ed36f").into(), + hex!("a670c4ce91ed3513487d4340914490e23484a99af144b7e1e1b7039368e0490ff9baf6b00607bb4b875dd342b50088c3").into(), + hex!("821006c1ecae5aebb0104d7ec5aac251df0de35356cfb746cf128b770eab158585463009c2aec98d5c414d8f994eed96").into(), + hex!("b55fb6db345697979f2139f0989402d8f588b63f36cd0c35f17267f381a9c81d04c1020f57d912ab684a496c08a44b90").into(), + hex!("a5dd99dd96643a950eb8f7f7a0a896f4e28ef0445de53e90a5356177be6a01cf80925709abfeab01935399176ac78459").into(), + hex!("8bb370c2fe54cf0913e3caeb2dac9b257665daf0a2df9d3dc2a2ccc242b63ee59e01f56f1ac4aceebdb756bf27eaf402").into(), + hex!("92b70264b3b2346d16b2ec9006b846e1ad2cdea76cc6077a12ac5d763e4171542825e0bc60acbb407eac3b4536d56d71").into(), + hex!("84b00b3c26f53fdf3d259179f552a75a15271be0ce3fca705fc7f3f1b6d127b3a34ff9da20c031691fca48e0d25a76af").into(), + hex!("a3b5b45d41cd19d6772aec8b12a4603899616df73c5ccff5ed43bba3a5e139375f3c34aa4a35dac5d19bcb14e709038e").into(), + hex!("a0b50e17eea8f7a49db3c3ee036e5275acda5a63abaaece7962cdcdb551bae9c9dbd6dba3b0660ac87b70f118d4ccfe0").into(), + hex!("aa213ffffa9fe9a1766540daecf880d13128893b993f3e3f820dc158bf6e63145661f4cde8dee54e93eb3e72e4873a26").into(), + hex!("acea701a092a1c20a48f82656dd104e5df953fb63f6456a9b6f92c651ceb649a66cb809230afdbfeb97beacdd212e4f3").into(), + hex!("996a0a56c4ef2c5c3c89c04d33b753d86b16bac796c1a245db0dc41e64e486e33a48ef95762a1d3b96f98063f49a5867").into(), + hex!("97581d036fe8b7b8ea18f257de7aa95b75632fbb946edaa2bbbf63d0063ed4051ac72263cc3428c0c2e4bd2668459763").into(), + hex!("ab439633e1b6f9c25053dbad8ef12818f86761e87544eafcea2b36f8764bb5367d315b1ad6a163af04426d8fbdc8fb50").into(), + hex!("acc80166b5e68e9bc340c222d9f29756ecc2d12e2eb57c95c5cfef5b80a70257c8243b987a45010810d97a97df16d364").into(), + hex!("a384cb4d518b2945966ecc2d245ee47b1461faefe20a011cf715420d9f57a944e88518f6f6c68263eeb646670bf3707f").into(), + hex!("8333a50d29d11eb786c65e8c76628cd65ce9e6b9ffab232e835164aa6ddb436563987e7a094ebd5c59af546fc6d24806").into(), + hex!("88ae01cc0213da8b2f16e93f63e5f624ec4970377feec39010273476509521f121ea41d1285b5d129ad94a06a4b51d12").into(), + hex!("a31c771560411b14f4f8356b27592fa219b979f38a2bdfa03934205664ee3aa180085b244009da441ac71b8ca86a29f1").into(), + hex!("a6ca38f66896f906f4318ebb6a0b9e240689caea8191651cff8b34f56e9ef6ca0ed93bfd2d78ee6e3fc955ce9f0fa8dd").into(), + hex!("b21acdcfcf7d501d6d2a3b6332c58f783314a8e9f44b9c7d7923f8b93a99c14f46286baca2f72011a6ef7186a48c6e0b").into(), + hex!("99ef4027f3a326026a5580bed545502cf5a90779e0bb99d5c4cc369d103a63af6c89fe771d3f24268ff5c682843ed065").into(), + hex!("9865132e53446fde02fbbcc91c3a6b5847ee51d7cc451110d1b20f5df9ff5a5974a6f7d34e2ace2a63ac88a2b964719a").into(), + hex!("b5923e99f6634027647a11ca55c360aabf6286378d27ff78c210b7a6d289f903f398b2ad2bd38626aaa2516f2836ad58").into(), + hex!("a00bd55b111c4f1ca4769f62db79bfd93b2bba5d3fd94cbfed00355cbf61ae0f8aefc2a5cd5b3b1734d0c9f1837509fb").into(), + hex!("ae3c02671387461fa84f34c1acca57b503f5f03cfa24243c57f83d0d017b2e8eac875b36ec95f48d05219637519c2ac7").into(), + hex!("928aff41ad76179d56137fc14a8817c8f8c35189854602accf2a2a784ba7adaf1699abf241b804b220115260ebaca950").into(), + hex!("827dab9ee6e8a5784c583f1c771d7eade45241185b1d570b2464de062a5c0258112454c6183dca1eb406de6f782fad13").into(), + hex!("97db7b2fa79801d4747f5dc1676359ef112a03de5b85c2cf59907e47a808e0f9245052241eabbf47b25caf30b7bcad6f").into(), + hex!("b886decf1ab08c231d3221574412f93758facb4af2532ed41083c900d669a6d55cac3eb8615ae88c16c0231b6ce18c5e").into(), + hex!("a25e9b94885e2a8a21ae99a374e1fb6e8156de6b3c0027e3c9320b45a7c9166102ad95fbdae36952ec2c410683e71de3").into(), + hex!("a9b195d76f05722ad474f98f4b328770fb8fdb79c724fa760df313b28c50731f57fe96df41f6ced5afa01dada6e1fea1").into(), + hex!("a0d111a8039c0b9fabbc1e420234929ec6b29a83e07952f406a171a1c987f9f638df6fcecadbbf1bdd77e365c3da360f").into(), + hex!("995476c08488a26cd347f807bda16e4c8df13add92324272cef97d97173a21586611ade14218b1ce978b5818fd3b0d40").into(), + hex!("a2c2a0510d5e776ef723331506299dfb7fdc3a7ebd5d1318877199c7d0925707aaae05aacae0de40143ab7228b2ffaef").into(), + hex!("a47c962b7a4209ee985bde3b15862a4a4790f56b08e1d615d9e5b03b72cff3b9be434cc2339eb3d3bd3825078802146e").into(), + hex!("a0e9c122cd73d0747b19956149afacf92a72f746e12f044582a78643a519687623d1fba45f9e889dcb6968bf42d6af42").into(), + hex!("a406aedfcf2465c07ec3488559895397a6844f2c97df7e679205dfd5cf594102ad92d4f187abf87856914d325b8728a9").into(), + hex!("b7078904d39c12799785a0302f9e9715ad9cce95baa4eb81ecbadc9b43b061e8a3d4e20c5ebd50c7bee6f5c6a5631079").into(), + hex!("ac88b1d06ab40d01550bc30768d07c8cc86959434e6f379b77c5b343651266046c496bdb3161be65185f174d18d7ad70").into(), + hex!("95ca4c68b81cb98bfca36905702153ca53ea70dd3b907bd4737c0f1391bc66daef371be513ddfb703be5c17c0c6ba94b").into(), + hex!("a67195c08930449ebb867a9eb330cdabb8c1c4d22c63f6395d55a8083e0aa7a4bb4fa1e6094fcb4c6979c86f37167446").into(), + hex!("b0aa1087abb8e25442ff9ea770f33387ec534392dfdd4faa09422e7065e701ea739e27a7e8f07b0bc6bcdbaf129ce887").into(), + hex!("887f47e2d76db44baa8b25e85f7aeccc17535afe5cb8046ab5d36eeaf95745625f2dbd58d40184de15d44583b5f2b7a1").into(), + hex!("b2bd6b3a5823f51cb0ddbba42aa98bf695cb23315b82046ca05412bddce9fbe966fd26eb079e4466a496c447cae7656d").into(), + hex!("85a42b1e305d836b0075dd9cc783515154b8b9c9eb98641f2d3e40ccf42ae7ab494c3d4b8bc14fbf7b9436e51f411182").into(), + hex!("ae99d82553b785d6055a3d4501b1cc85e03fc1fac06e09b4d55ada6d5c7d94f28bf39a7366466045241b55d7c2faa743").into(), + hex!("a99c9a32eacaf96184cc59678a70758aec1cf8449a43f07b028129bf59e4a23f2c95677f2362a65069ceea2d2c779f0a").into(), + hex!("8a8363bcf63de18a42531b3ee9ec50b649189b9ff7b3c5e1ec71a624406a74967a4e036a615f2aac3babc279231412ba").into(), + hex!("b17198639b1cdd2ddd9ae0db2a4286343ae3bed6d1324f8edbd30e4de9a24b03c2f0056c1d91864910b8da394288bd45").into(), + hex!("a4eef40a0ab80e78e4d333930cab48f4a754949a8f495566876af5176abd6473632ca5eb924914c2e4b8bb975ff3b8f3").into(), + hex!("abebe936b21160e3e37bb6f72dfd9788f4024666f425b1cd3ff1b32ca3d0162ff801bc6d3c11f8434a4d7942ef3c1080").into(), + hex!("8e6a31f7ea157bc1f1cd24bbcbbbabf5809187e7aa54f75ad43232c8662bda69923fa3785bb1e25e82e29f8ecc91a7ee").into(), + hex!("aacfd982eff769bd41a4679cb4eb5082aed961c898be080c411a410d5e0e4043150e0b1a08e944d48a96750027c3dca9").into(), + hex!("85ec172e1de9adfe9e8dc502e1d58ec3a313d5046b2420bde2b553cbf56e8f95a7fbc45452f4a827db963a1d60743a68").into(), + hex!("8f07286936f74536ea9f924c14034889b7012944cd20daf73310ba391f7f929c595b14f54cfe4cfc9802c62ccf047c6e").into(), + hex!("8d3f96a8eec337ca12fe15b57950953f6c6b0c6be3043d086cf83e04227b7a20d740552ccba1db10a57a2357d46953db").into(), + hex!("b42da80d7d783a1ca5a385f9213b328cad07726d6951de01d76663745d9dd2c04a851de9a49dc069d646a58000c214cf").into(), + hex!("8447f82d0b0eedb86c38a43c0db2a898af74822175c10e4bb8ab46d4887c9a454ddc0d1519f405eb1e5fc307acc78eb0").into(), + hex!("a479efc07aab1462423cd5dc57912e1141f1ea777905bbb2a610568ad5aaba57c02402e3b25d2b752621d783fd7dfc8a").into(), + hex!("b7d801eff4735bfdd687114d03794a63ee7da41f9b8b866d0414e9eff900a13d70eb4891cc1fe23acafa35b9b84f6a43").into(), + hex!("98a08bdd88ff735845a180624229331e947b130aef4886ce71cb9a9a9fb15bd74cbcdf06b5c457e65e784991e0ead210").into(), + hex!("89cc6a975b8a939b56d5066fbef61c5ae58ca8b084b7ec7b87f5c887fec51dbb29bb6203aabc67ec3d19075adea501db").into(), + hex!("a59ea501956765237b3242efe9f07e8a78ba0aff88ec538d3d6d54e8dad0e2991ffc3ac33e9a485d8503e0e8176c2aba").into(), + hex!("97c7e0d555463d3eec25332779b613a76a80a58e79d843314a3507e4da88b59e3fef79dd6c22404866308e25822f9cc5").into(), + hex!("8a0ee7647b7751e4504813f419ae6b507734b7272a80a434d74cd0fd904908df3ac03605ee7ab9ffc2c948d02641a231").into(), + hex!("92cad4a2a986fa0840fbdd4bf4fc84949c55bcf4ede49f371321665b5f5be670f8f9b274004b9a90430c07b12496a4ba").into(), + hex!("8631fad25dd9f59044a1f1dfd8f758f1ae8cbc7187c28a7d0040fc3c0bd401c8f72636b36f61fbed0cd793ee322ef457").into(), + hex!("93c4d674fa1c7a54ed027a590afd5860754dfc48566a6b6a64b7c45569bf8e6f12426488779e75f6f10218e2e32404ae").into(), + hex!("a52f19cd98c7f620bb4297635998f262908501588a5022ccdf733f463d9c240733b41e770ddff19f716a130dcd62e6f2").into(), + hex!("98bdd81650db9b8cef44ec5c0014212dec415e71d96fbbe82d412468c70fcbdb508b8f009b83b1f63eb09440806107e0").into(), + hex!("a99c9fc1d789eabba6c2be5fad1bf3d38bd4f0517796502c2cbfb1173decc748863007aad15c9ae0df72ea098a82f3ec").into(), + hex!("8301741b802e3261c2fbb31a1c8ebc3b0646b6b1aa32a0df4c590d5112e45d7c32b098322c430859f74c3541886e5cfe").into(), + hex!("843a017a6dddacc204d41707ef328035cf276625beb54cc228c43adea843d532fc947e7e24c0ceef6345c9dd8a2155f8").into(), + hex!("85a729df4d0112cbc7d15abd45ac9ce3d687cf515f6e1d4a9423a080bc0e63e352d48148f8d24a91011caadb64db9eaf").into(), + hex!("914b7d7be374bea5cb27fd208c6cc8969671e7d05cb38aec484b8be72072397f1c293622deb72db55ac81d02942b6714").into(), + hex!("95bc325e72f609a32b2f91df8b19e62cb94f53dbb5abaf1f0c47d7a1b99b7c6e70e4c490bbb1e6fc13fe6e17e6b0b4e2").into(), + hex!("971d0134432d38628e36ee164eb4f1396244689d60b7b4b4146bd302636cf97698d53e50604e6d2d702abf874483aa35").into(), + hex!("870b8a6349a8f1e848f18094c1a9139b94e9f41a4522059663f5a23e038dbc7356050e6a3178caa752d2e968c6ddd14a").into(), + hex!("a03f5a1122018dd0925456f24169bd78fa0451c4c7d005b95d301b9fc9e71f297803fd47346838eda26bbb23a1f393a1").into(), + hex!("b7df50fac8570f66b0d3618e157346ff30a1d80876bccce4fc59d0f4746cdf2aea64c0848916a8ccb3be57ca6681c206").into(), + hex!("ae6beda3480ca83ff31a2c96100332dd322cbd8084e24538e4da762a0f57764dd3d53ca0e60be73e909b2b6ed38933d3").into(), + hex!("9018c0f26b6cc9fbc7299de32bf6539da6f782b7aa88003862651146ebd2329fc2b3c363e53a8b6a492fb25b34079a6e").into(), + hex!("b6568bbff45feb5d4ab56fa0de8cdf553f3f55e6397300b54b4d9c9896d29d3624ff2b147669eae16687f4efbdb9281f").into(), + hex!("ae7f790bf8f7967424531d927e487b3aa7674d15af1c48ae4666c4977b21dee6e7677eb396face00cec227f971c54153").into(), + hex!("b6007c900963430fdb44dc4eaebe45ed57a28f930e862f19fe51cbae7d28bfbd74d4419aa5e89e7ad605874e79abd74e").into(), + hex!("8a0e314de43adfb794dc62f1f38179db784d0b21bc9e7e3b68aa1564faaa552ae0f7a625c1af47d8d71b6d4793de05ab").into(), + hex!("a272117258dd25abc0b2b4d82665f603195eca4ec75331e3be5cb8a7c68265a3d3f564c95d1600c92758854ab4202f30").into(), + hex!("a39bd0f658efab6769e1fcdc3ee1f73b4ddc8a8433a680bb87580a9ca039eed9c77e99154dc9ccf0c0653661c6003a36").into(), + hex!("818954f810fc9a23c26b01d5d1df5cec6d233ee311fd10f42410e9dab0253525eb722d6fe7c7c49ce874ca23bca514e6").into(), + hex!("a5e2d68cee00a1113ca3aa7b9580212925615978964ff44c925d0dbd1cb651d02d708307ebb737383659c3f1cf126f99").into(), + hex!("a7a5824a624e9bff77cac810356e3a0465101fdaf5c45f261314684f4ebbe9a0a3216e720e10ced800f35e213508deb9").into(), + hex!("a1c170e7f717e1c968190f7724a7f65f74ed937964ad5b479710898e4062cf14e42bd82fa7078cfab131bd414969cb2b").into(), + hex!("8a3399e1c7e823265cfa881e2945471737f49e57b6588435b7c5f864af5e7fd657236769283039fc6a4d19c3f8a7d446").into(), + hex!("a048621fefcef32087074d156a4c21596eb140d3afe0bcfa1554a7051fd891214caea2bb08367679459c9a1b5ba68490").into(), + hex!("945c7cfaef7daf66600c3d2180cd96dc826f16e51e63302229e3d5d5182e608b648855d6065aa417fa45a13f547210f0").into(), + hex!("b5d0baa42f71c704c3aff972e71bc4c0b27738889f8f2fe287fb9f8a1a612bbded227ffa7c8c2316b3201232d95563c3").into(), + hex!("807fcd5b6e4c45dd212b07faecb9e9570ceaf552465105763423203e24a81af829772ac016faf77dd345846eb196b906").into(), + hex!("a4119c35d4413dfba3c53985d9a85ccad283b4aea12d006c02e5ee34dde5f63566ebe16a5f2364fec41599590178e8bc").into(), + hex!("93641254d7244449df1a3fdc5854920cd657a2aca3bc1c08c928769d68a21c9017c725650ab7b4eda965fe2cdc2a9f85").into(), + hex!("a435e70c98cc0381ac1d048438b0f4ac6cfb06d5ccace73f1565225867446e4f306572ecdf4b7d8fe2ee496274aa2329").into(), + hex!("a1b57422956839188ed7490eb270b5c4171bd932fb5f7acafaf066288e8ef5f606de7d60aee350fb211047ea4b010c55").into(), + hex!("b4bf1e7d116e2f97ee8460fa0d0a3c18461dd32962f52cc1ab93440d9d34972d0160b9d15ed6cf77133c751591bf1e1f").into(), + hex!("91c7238db88203baa821e4f2082e217dfbf9b5cf15c3502f186fc250a0680fbac1a52aa9f81ae65ea3befe64ebabe9ee").into(), + hex!("b889f347492dd365f29b3c8b70d7d34908ddb5e0dd53eb54a1696a1b120b9595fd1c71e82a600178e42aecc028d68700").into(), + hex!("b7a7777e8c64c78fa50a28af53e6a13846a28c00b882d47e1f614dcd9d23326e82de960f24737ea087c896c5eb66b28b").into(), + hex!("a929df1583465174bcc69010f3ec665726ad0b2543a89b5d0cbcf1ff2ef4b7617b32cd034c66341f4f6d5522027d90f5").into(), + hex!("972e39f2f85e5bbe8f51bf2261b49d913a44213aa096f2a38975044ef284e112cda9867bf1e7413bf2fd84de17a46654").into(), + hex!("b4223ec897565c998ac53d5656d66defc3f079602e8c3bd44bf4bbc95a705d6d58022a5978947b02d1ccd1047010d173").into(), + hex!("988969ab38ee989490a540344ce9f3ba1db11f7a70e6143e1b3f7882051a84d5a9c0e7ac87dedeee5b57a21e9ad6b6f7").into(), + ], + aggregate_pubkey: hex!("8f655c5ea450ca6642be30574a2bdd4cb674024a3c8a4705219098cc75e005498d2b62d6595c56efde6760da64078d9c").into() }, current_sync_committee_branch: vec![ hex!("d7803c3cd7de0f5ee6a0ac0ea03a31b82e2ce60992dbe0ad7dc1bd6a22ddcf1b").into(), @@ -544,18 +541,14 @@ pub fn initial_sync, ProofSize: Get>( hex!("a86ee98ecc96096d36546582c0934ffa7ca17a7e4f5c0c996f747500d91e4b96").into(), hex!("1d456d421e6623eb5eeac42e1fce7b67b3b95283866e358dd89f2b1fddacf2f5").into(), hex!("c896dfbfe78d9aaff775e5aff310657c7af9377c31dcc8361f91699af8859227").into(), - ].try_into().expect("too many branch proof items"), + ], validators_root: hex!("043db0d9a83813551ee2f33450d23797757d430911a9320530ad8a0eabc43efb").into(), import_time: time_now + 97200, // now + 27 hour sync committee period }; } -pub fn sync_committee_update< - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, ->() -> SyncCommitteePeriodUpdate { - return SyncCommitteePeriodUpdate { +pub fn sync_committee_update() -> SyncCommitteeUpdate { + return SyncCommitteeUpdate { attested_header: BeaconHeader { slot: 5217991, proposer_index: 447822, @@ -564,521 +557,521 @@ pub fn sync_committee_update< body_root: hex!("b2e84f802061f8f10120ee0c355d129ac853412ee1c2f9067755e14084a29ee6").into(), }, next_sync_committee: SyncCommittee { - pubkeys: vec![ - PublicKey(hex!("aa10b12277616e04b54c1890851347b31be15bf4c12ffae27865cd2ca6c9b9506608b06003cd0b2bcdc407dc2a231340").into()), - PublicKey(hex!("89f6a874047f9cca4cda217c90e461dfe8a91b298554090e2880a22806879da585fd6de86d1d6c52a59b07a15c64cfae").into()), - PublicKey(hex!("a0f7e7e13048b9953dd57eab7591f725bf70b4ef05d163eff09702a665aeb7cbc350e37f6803a42095167bde9a8978ba").into()), - PublicKey(hex!("b7353d4ffdce6fabc3df30a5fda41ccfaab8c251c131496087684fd1ddeafafe1b23aaafeea77796d320a5b3a07a77ea").into()), - PublicKey(hex!("98428fdecac17cbc38e092b034c5386e71e2b4806410e46a5dec71eab36c91faa806999319f7e900d432d2f8cbd34fc9").into()), - PublicKey(hex!("8bd4e1dddfa7f95991f2ca85024e70d455de2d63a97033624ec266e48ef580a1f4ec446a34ce0eaa905d1ec544de98cf").into()), - PublicKey(hex!("889305e5eb4f4bd4760a51d587bcdb28742c3beccc52a0aa398929b57e43abac4c47c6fabff1cfb345d4a245079ae02b").into()), - PublicKey(hex!("ae8afee1125fda446dfda84b389acba0bc3b840e237be5b78f388f43c09480ea3d5f69d2ac9796c706f443889c6b0479").into()), - PublicKey(hex!("8ea2b9beaa89dbf9a5ba60c4c97bfbb91c49cf7674dbea8e0972ba79aff151c0587ca46355c6bea53dead0af5186d92f").into()), - PublicKey(hex!("b9cfb198d16afd865b81791f4ba612af31216e3a6adabd37399b28c880a1995d6c935b4c8a078802e371fa7081136ccb").into()), - PublicKey(hex!("b2a39cedeac0ab3273f40560082df9ed9738303892d0d9705fb21e23e2d62e1bacce1734d2571c21b80ba992de68a165").into()), - PublicKey(hex!("83c8701f1bd6013ac09502b973943fd23143bc2eb62068b2a0b4c5c87cf8f70d4a70a05927e0fa8cb531b6a0393428ec").into()), - PublicKey(hex!("97067f80c6a90595349b903021da1b1590f026e10fc9d42440bb6dea8b242c995c2d1a904766fc75e32cc36f2c0517a7").into()), - PublicKey(hex!("9051082aaed9467dc4f2e458a401fb71a6fd3a709430df4585cce8b04d47bdedd751fd4fa50094b10de9a33cdb3ff41b").into()), - PublicKey(hex!("93524a14ad77681723bafeb9a9a376283e5f3591acbf7bd3b08695bd79e3d0daea6c47b83baf4dc54ee5947276637900").into()), - PublicKey(hex!("8724e0e971d0da871974bf116f3be430ab365712818e45993fbcf73d223d6d9b8fad5c67d680feab4ed1a503fdaa3520").into()), - PublicKey(hex!("83a950e236b8e4f977eb39d8a6c4e8c2bf6c39d189fe1cfbba9627aad0185e28355b8154d0b6ccbb6671f3a9b005585f").into()), - PublicKey(hex!("82484dd8925e733f6a4b270267a28a42724629e9eec292ae7d916a3b96268293a728ec56178d5312367afdc99e761674").into()), - PublicKey(hex!("8dbbda27c58a35c166ea8f5bfcfa7e29736bb0f70f904a825f583aede1179c3f84396df96eb1c6581143f6af6c546456").into()), - PublicKey(hex!("aee74d86900a0f5d574bdad370474e29d3542bcf80fec415773a760ad76406e11af6cce57415f19f4905597f3ea626a5").into()), - PublicKey(hex!("8127062000d519c88fd55e990032ed1011c16f8c98879f7f48c67965326b89564ed92b2d25d1767d098ac197d7b46ab5").into()), - PublicKey(hex!("8d34fd5aeb4081c69008bf6ef1d93a457ff602260206479dc90510b0bd2196aa8af9c81be124c05776af98b520deabfd").into()), - PublicKey(hex!("8376f851c0522225a9304dc5256fc4326a11b4aa0b1caecef0107bb03196d433a3386c66fe6de6459b7036229ebaf2e7").into()), - PublicKey(hex!("b87b88814563fdcc24879237c8799853a41032729b586c7018a6200f589ec2367bcc845449def6036d5a476506c54914").into()), - PublicKey(hex!("a06155545e152ed95ef87d19c9afd3694e1e1d65732781f385f2b75780661a50adb5499541f6f87e97d6483ef763e538").into()), - PublicKey(hex!("852a0bdf07614d90e4830a2be038466c6109cf76e38467229f6db09c3fdeffe3884588a26eb54d399daa8c64077f5ee1").into()), - PublicKey(hex!("ae7548136e5c228994a6589e8aa4edd58532b1f5f8a11578345103c5b54af32a1e481841ed719000bfaaa510cdd7f1ff").into()), - PublicKey(hex!("aa994095d3a6fdc739e19e312452f08b0221484bb2a98c1a365859157ec454c52e22c812a8ca331fb1bf037482a5a325").into()), - PublicKey(hex!("8f1ad2801414fe75c37d87ab6798a617f6deb791f72ba08ba64fe512b26ed5c72a84a5c57c07bb31bead1c236a698116").into()), - PublicKey(hex!("8326ba55bd7d8edf114d8bb840d8212ddff6c8c4a33c86da11ec4781f8a4aec71fb3bf0e44ff4348a2af3233aeb9a9a4").into()), - PublicKey(hex!("85bb0795baa8c2c7123243b749a8d71a80108d4d197bb1fb63f5a375a534e9fdf02c5e729e562a8520fd672a93a9b25a").into()), - PublicKey(hex!("831b11ceb6175bde7a2c532552b935e18e7741e2c93f747d8efc37261dcb4278e8deb88a2cd33a6011c22ca9028d44d2").into()), - PublicKey(hex!("ac92a37a0f7d665ef778dae08d9b7647ef9736ddb86b808cf8c803bb487943bbaf54eeae5671015421abbea758373a89").into()), - PublicKey(hex!("abb177d8b257310969ff65c954324eadaa6b989f01c4bb7ae6b14fd396c5c3106b05e7e5a6dab0a866afbdda2142656d").into()), - PublicKey(hex!("b5603023eb7ffab692004b8c39c58b46de413c39ec86fb1dcf1709d246bb7f60363ab711c23bd9bc3fa39baf2f0fc552").into()), - PublicKey(hex!("80c2ea7213c89c5fd01e3fd6cc7d74ccab278de9cd6065b42f3bef8ebc77c49aa4cbe741d9117afd85f0d675895ff0ff").into()), - PublicKey(hex!("ac9c0f11c456561b26d7ed72391168fd4d7d7a3b2ec3af3d89cf61c804984e239d5f090e73185d4368a4d1c237574360").into()), - PublicKey(hex!("b96b4d078b6b87e7d1cfd58342b1816e1cb915d9ead3307c2751f72796ad003c5824bb37291085d2a2451b4d5e2213d1").into()), - PublicKey(hex!("8e3d805de69cd4f81b9952b25ff65b0790f103ea91d855e5ecc97586e5119078053e2bf4acb60d5a2c9c608925bce539").into()), - PublicKey(hex!("b6ef3efa283b54dbb8e4a24f715bde06d90a12b7e86c260124e3323b3b67c04124ed3da23d99f23d31e050eabe59452e").into()), - PublicKey(hex!("ab472c2306bb00fdf2bbaea1dc59e04b96c9dc52cec10d2a37b2275b79678fcdb4f5a8a23ed6e1c2e10d174669358998").into()), - PublicKey(hex!("a83206310324ae9a56c35ddce6440abbb0478a755954d70024f7cd26a80fdab40e462cd361009f98925c9888cf12f3e5").into()), - PublicKey(hex!("a3d9776f078348cf2efa9ebe2b7174fbe1227d70af24deaf2aae0bc4e808b256cadf2c35c10d27b7016142b23a8b5c5b").into()), - PublicKey(hex!("b40cef0f8e65047d0607fc331d55436477c6024deaffffac38ad4518b79e6ca0c33dea4e001c845fa835c032ceb24a8f").into()), - PublicKey(hex!("aea4c67822c5f24a3e17685c47e19d9213b763eb613734e128c2170ceadfe656fc3bd782e75396b968518832eec5cfe7").into()), - PublicKey(hex!("b46697edf5e58554bb9f0a504efe4e27abb883144fb3bb02e1b3e60bd23cd1878f47ed40e0569ec6485d70ae156fbfef").into()), - PublicKey(hex!("92d97bf88a72b34824c8c406265f166e59e91840272ec9e51616b0bcbb579f371814b89f532056e95829d4e4b28abd5b").into()), - PublicKey(hex!("85929bef887e0ceebfc3bdf733448dc8070a484e2bc89bfa85663a0b30edbdaaa785b36fabf6d2ed01b7367a99761f94").into()), - PublicKey(hex!("b3f330ef59df39e9150ee3ff6bd743c9e5703744e2663b7bd6fed15a150d866b5b61183045aeaf9885f62764c9a1e64f").into()), - PublicKey(hex!("a15ad89715d236b062878e75cbf8132c55db0db3f65ae0768f44501c0bda9c588b32d063f4be4d7ebc79457c58c561c4").into()), - PublicKey(hex!("b43e3573daa78765e007ac63c3ba06f65dd1de3b6946aa835be4568866ab802842e7272502f208d0e99e1dcac782da6e").into()), - PublicKey(hex!("84e02e4ce82d96bc3740c8aa00e1a8fb7801ca9ad1489290d636c20073ddb0978fa54191d8daace4032b92c8f0b85d5a").into()), - PublicKey(hex!("8d35f1c0df64ead05d55ce5a7d6160e711d4e7460b049638c2bc2dff3b8bf879e1ef8ce5ae14d029ee43eae9d5e99ea2").into()), - PublicKey(hex!("8c2f24127ef6b4b6d18e18602cb146ee8c7d4d3c031d97d94987ce5291367ee344f70c6784d55267bc6d646f3b47a934").into()), - PublicKey(hex!("b127067473276cba846054c18d6ef4eea1e2432b6d3d74624340c6c5a518eb6998a09b0a742b27a7248f0179ad0a6f5d").into()), - PublicKey(hex!("887d21a5d456d0c52ae3387163544791ea032756bde11c242c56e378f03d540c308a9dbe75b003e9f160e1498207921a").into()), - PublicKey(hex!("ad9b4f0aa75c6df3a0717552d660abcfc6969526b3733a1c0b7e74a4214f255698b2c981c658128757ecaebddd3e9847").into()), - PublicKey(hex!("afe461e86183e7ac6dfbd6e0dca8425badbec62fe9498307e685ee3d19b608fc203032f7fd7e844ef299660f1568a97b").into()), - PublicKey(hex!("a52a923281c74043a12889166e6cd5251c0845015cea25c803c99b5d5576deedf59ec38bd27e3edd2241d95ebf1e58ef").into()), - PublicKey(hex!("b8298341fe9d74ff885be48bbe359aaf434567c701cb12623ab186ac72f591f518b87e87bb2123789d810ddb73d45c92").into()), - PublicKey(hex!("9882282e1aed4adc319f6d23bbd1cfbf0a7b92e8dea663880f23d30bff0021d381138f7d949addf973bed505183fcc8d").into()), - PublicKey(hex!("a56219ed90a4de900443687a85822e5be66cd864c480dfdb06302d6d4c1bf0c807830575df04eb394c0c4e484349da1a").into()), - PublicKey(hex!("b80b6b57e35474b08196557f50a7f8c9b9460613a34a933f269b5b051bf1dfdd195c17f5fc49bcd1014e964e01ed65bc").into()), - PublicKey(hex!("b8c4afb97771897df3fc80dabeeb39111f2e1bc125d6a706dd75ab7c06a6f8eb5691e4c88b406c1e31c76b0ad24421f7").into()), - PublicKey(hex!("8373499d411faf82d65f845679965c4807c426851a881f5fadb0a580753c2889207c4be6b7f198d21a460af0af6e04a5").into()), - PublicKey(hex!("b50071e910a81f5b6d6d7e0921de061f82a1ba0bf97a97e29fa4d07d07777c71765ef9771ad74b2eb4007cc98c9ef9e9").into()), - PublicKey(hex!("a318d357afb13d0734d35df715f98e6572f93e0dc0d271bae402581593f9c0fbe931e623b9b563cfcfb9b226d96d8b5c").into()), - PublicKey(hex!("8187b65888a5da17c99735c4a1370865e475394426fd2d47fe20fc6046679d10f12f9524f34023f49b36c84009a55681").into()), - PublicKey(hex!("ae9811057db9d5c2be1ad726a75b40a664ff920f267dedcc1f71a27b9cd96ff0e0db5a6b17d638b9a716b26e9693f5e9").into()), - PublicKey(hex!("a996d50d0aba322da2cec279aa64eafe9af5734ee6e0c725b9cde9b0f54ba4aae97d57022f47fbdd0ef09e0bb9003b5f").into()), - PublicKey(hex!("a3b4cfa2c38f23bfa67bb8ad8d912a32ef97d5520ffcf8f64da415377e80df39d67ae925dbfcec48bfe941b473eb40af").into()), - PublicKey(hex!("9640b1c78e1267fab0c67d6a902c40473bb33955cc6498970ec62edc8dc4a9f8cb4eaf9291f618ad3360ac33ad792158").into()), - PublicKey(hex!("8791faf25c0086e0991d7d14533e461ecb51870f3417290f490b034514f0604cef0812692fa92c6e6683f6c52d260f46").into()), - PublicKey(hex!("844134b6c2662e015b7e742979c3395e05e33490cb3bdbe8490771c5148cae6302e06ab5c707a103784e2358e43acd98").into()), - PublicKey(hex!("a1ed8d46779b7adb0dc3727e7ecc3c4944a60e6518093135bb46dacffca21643efb20554a30c4c2fa73d53fe59faff79").into()), - PublicKey(hex!("b20dd15e201c445e6cf5a49a2ea2979cd2339bfe21a7eb4e996f345691e95e630a516f25db007d83ff6a96cf63194eba").into()), - PublicKey(hex!("b7cb015a991dbc2fedd47e0dcc66af30a86302ccbf13c9f1d5020c4fb54a86847b0ef64acfd61e84e582c3153cd94942").into()), - PublicKey(hex!("8cb6d763100ac289fbcf7b1d259baa6db4b00bb220ff0e97896d47ef1485e4cb01d24958eea5dae6838b38d3d74550a8").into()), - PublicKey(hex!("81d1c5e7a4b922583b02dd8e328cd564358ada1d1d58076262c5a1bcf7416e6b9988f081ff154c0acdb2de869fa73424").into()), - PublicKey(hex!("8746191d3e3ef97dccf935b16b3d306b6a5636e274a78ea7531561b3ce92f97437911a3ddcc63ebe34d875d9e05a37d9").into()), - PublicKey(hex!("92689db2982fa1793d8a76a690bef928b59db01df1d7c1b8568a8f8fab825aed07dab7a3ab277e86e2307ef0d3a5656e").into()), - PublicKey(hex!("a1f978236ec0e3ce8af63b19b6523c237a8ce435b00a17f1e5d627ef36a3c1f8e4cbea6bf2d455b9b778ca7c091371ee").into()), - PublicKey(hex!("867c2b702b2ceb2c10d94e86c44ec39d6faf2f92c5f8b6030f95b6558f287d47b027fe3032ed8e993f6cd6056aceb8a2").into()), - PublicKey(hex!("97ae230a44d3318d8c75308f6b473194f62a884369c2c636963f82a11f69cddcfa397b28a3b457d9ec81f47d7e1718ba").into()), - PublicKey(hex!("95712c05d56fcef6342971e71f3d3d414b4620adac8d434f83735c5d28c44ae25853683ef24f876a0d3480f4e623a655").into()), - PublicKey(hex!("a2a22ea77a0bdbfb6d1012ea3f5446c164895b9862ce9e347ba24c9ac054a0db2ac920975ed1254d744bd64b08761f88").into()), - PublicKey(hex!("81dff1b4c03d2ebb1520fb7fb8ccb0886b6d5d4620e8c9f97ab1da39e67e2b29b668a63b69ed7d97fe25db543bd489e8").into()), - PublicKey(hex!("94786676020044db143c3ae7218d5cd9c2019dde9e4868b3701f1fa7c28d54f82c8f50dc60d68f01712b1574ff912ae1").into()), - PublicKey(hex!("9318341a07e78c2562a9da9aca75241e3fc7b68380c5fe636af37b053da41aa48624d2dae24d057b5e8386d3a35abb57").into()), - PublicKey(hex!("a8930bb5ceff7e1ba192192b14f75a3381eee0bd6f6a2c67f43adc1ce57ed1cbb64a3574be5ef1515153ee6aac51d809").into()), - PublicKey(hex!("88a16ed7ec1d78568532b4d3050c45e0016d9d1b896e9b29db6cbe2d976dc9498cacb7326186567f621defb9c4ed3ad0").into()), - PublicKey(hex!("8473c467948aa778e3222f5cb8ecf25c53c975840b6a2eeaf25fd5d1c89a5bd90fefa3252269f830f69c2b38e767dc33").into()), - PublicKey(hex!("a055c95fb4c6b0827b6965e2cfadd2e37608b18ce9ac5830fa9ea3e97d603b9317bf5ce736782740276f9cb5166a2970").into()), - PublicKey(hex!("a62f9517ffb9b0405a8ad4b74ed900ffb18edbd5f59fb8770ec4b282e91d7d167efeb95d7617eea052ed8e0918de77e1").into()), - PublicKey(hex!("a7e9563d9fba807036915a564afaf7b93bed7c9d249d68f5a6c56c2cb35ed14807441a92b813a0c69f63691f549ca400").into()), - PublicKey(hex!("98ada2b51e8fbbf4d101fd78dde440bfe73d585a836e00c5ad33586229c919dd3d087fe4db2ff994807e91eb6254297e").into()), - PublicKey(hex!("a68fc63e1474fe08dc03a1d059fe6b928f48d6c9662e9401e41a5c4ee45077a1c904d62c0b0b76a588e6b38596935214").into()), - PublicKey(hex!("a8accf1025794d087bd36adeeee1e9977fe656065ee01edf1c3e4324c6a1e2e2dfe95e68e1684958759e90ac3d939de6").into()), - PublicKey(hex!("9055a0df50b948af9690e899ee4fd4a7251be2175067d20190afef112c4d1903bd78ffc380637eb3624ab0b462468b84").into()), - PublicKey(hex!("b5ea157f31830c779f2e7557d53b2217b686961f66eb3335b5e3db49e099094b61e9202dcb90af601c416d0be0f8059c").into()), - PublicKey(hex!("833ff4a7e06cc8705273ebc7436a957b4ebbae02b7f76032d1a22261d71d9d3183ba5944fe53369f46214ef8425d0f3b").into()), - PublicKey(hex!("8bcdb48edf6211687da8cf2e2173c1f67fb9f143e4a92c0ca2585feb2463d624c933b6a7fce9892ce6bd9c657b8c634f").into()), - PublicKey(hex!("8cd3e12538cf6229c54826fa6a404e9c0fb167f3f53f1e7354772b2a87544478de47d3c47a01970db2054605aaf8a75f").into()), - PublicKey(hex!("8d3a4b65c0f9cb4ecc53b6472169256347cdc3f5d2a50d87b8f6d1a3234f8e77ae8a9354e624fd6e15508de60cffa586").into()), - PublicKey(hex!("8759c327af5e9d69e478370a07112710d9e0a03ef5db9f4e4d83c2e980dec3d8d233dcf11227f46cc40792e00fa181f9").into()), - PublicKey(hex!("8a72c3f4e4bfeec7733b532ded35dba7769092d16967d262a7d215b30f203c18c561d29a6e205f36f4b15c7001faab50").into()), - PublicKey(hex!("ad0ba4caa020d4dfa4a682bc33ab5d167045eb4276ce777d90a271d9f16ffb3be2db5ea75c0469a168d122a374096375").into()), - PublicKey(hex!("86e4bee1e0c694102350539f4ba08498561c59784d39e1321f175e0e4315c5f4795b82a2bc0b8c7fbd840a1d4861f5b5").into()), - PublicKey(hex!("8aec422f9c614bdf7a14c20e2666a48f274e1ab2583826dc5a0fbd3f8afd9649fb5387bfd95f1b3aeaa8f1585a767ce8").into()), - PublicKey(hex!("8f553b953034dd409506191b021bae2a74ce76f6a98cea0264a9a97f79ecf6105fe17287b805eb828bb7e486779bb780").into()), - PublicKey(hex!("a8e9db981359b0ece6dcade231c2f6dcf915685e13550531c47dc7412416b535cab4c12fcf81c19a8606659145d3d46a").into()), - PublicKey(hex!("9797b7daca1821cf6b3aba05e5c78099506ec52fed5179fca7a880e0064fe1876ed83c607e50b38a11da4c57a774ba39").into()), - PublicKey(hex!("8bab1f3ebbb480b879760cc1b640d5b97538f069b04fc85bc7860a3433d03a744606328801d6569fb4c822c1f9d7adfa").into()), - PublicKey(hex!("ae1acf60946e115a10678047aae8fb40872bbc4683b9fa42e74d25bd5d9d49be6b5135dc989407c24daf8f6c12dd7649").into()), - PublicKey(hex!("a01836efc39ff41c9283d90bc532ccd4aed815f5a6f71b3704e9fa9eb718b67b15f45ddcb00d054c5687c60d9b66cfd4").into()), - PublicKey(hex!("b38f914bfc4d78dbe99c8c2bbb1bfa7f3bb92a22f7a842573660e20c0114059dc6e79d03e09f8f2fa3ab33c1b36461cc").into()), - PublicKey(hex!("9774a19aa64488be10560a3ecb4e36cf1c826ebdb1c8875378197157caa2b2cb048e32e3ff16074f5442feff3ce7fc45").into()), - PublicKey(hex!("b212de79a3cd09f855b894b190a2dbffdffebbf18d2ad04bfc26d195252aa52cda5d41b1f7a42310c72304b2b28a4f77").into()), - PublicKey(hex!("92621904c5ae3987f9466624b2a59503eb3565ed4e44c756109ff105c13949a77bea9c4bf58bfb67c9e5473b315f8d14").into()), - PublicKey(hex!("b393161e88cf46085bb85e5f4093cc00ea9f51b5813dc2d9f383c4e8f5ff8377070c7c9740247271beb58bb8813d975c").into()), - PublicKey(hex!("874544abac10a940faae6b06edb927bd4cac1655a50c2ef5a99c7b1017f513d1cc3def82670d5a67a11a0d5fd6eb1fc8").into()), - PublicKey(hex!("9630062d01374a7891ae58d7f1b096d6d5c4826f9518a53e65e7b9250bf319f84451a0d7a95af9134fd02c852e08c620").into()), - PublicKey(hex!("a53046d57bfe1c32453af686ae7c7e751cd2884d7a1d4de327bad9c10cf49550f32bb91511bb865b92db423ad6120fdc").into()), - PublicKey(hex!("96c0053f673daf98390554999ee32550e14597b2350acb9717f87cb50e6218489d694d0a07f6922b2556f026aa036fb0").into()), - PublicKey(hex!("94baae1e8125cff266629c493cfdd0d98fbf6fcf5efac9661bab0f25cb206240807787c718d7958413ab1c2bbff35af5").into()), - PublicKey(hex!("9677f6ff799d8cde162e05908d62cc708154450bac669a37c19f18fd4a3214a07bbb50d020b8251dcf7505fecdf3fa73").into()), - PublicKey(hex!("8641688e4052f636291d102a0915652ff70f2d372ebbcbf5266cd38918fb2da16bd3df0dee83e11c2845a10660e5ff13").into()), - PublicKey(hex!("9038685e59a59ead27e2989524fe0f8c7ca43b6b1d4a36f3946d3ce7a3670c15e7beb9e814f7ce65e813ee091a2f1be2").into()), - PublicKey(hex!("8afb4c7e592864a52c0866cab38bd640cf355e6c8db9a2a4f8ac1917b0cdfa6e9e597cb6e7fed7a0043f7f534a0743c4").into()), - PublicKey(hex!("8d5052fd8accef40c9cc243db4d50da074b416e743310042d941e851e6e866242561eaca905cd1d3277f735ce805ba36").into()), - PublicKey(hex!("b76e333a2718c65ad531a0d9a60ae8bcdcd331e5c87ad3ff0861f00b82b3cd0d987829c50394dd54580d83e2cc51ee26").into()), - PublicKey(hex!("b4780edd4af4c2b4ed559fb135255aa3e4261102cacfed33c835d5ff603218166a75d399f9e7fa4ea807b0c131058ce4").into()), - PublicKey(hex!("866e7efe22528e237dbe49b4c41f7b495617e9454f9e46d7ee154600a1a471996a4194b2a14e206fc7bf0632486698bc").into()), - PublicKey(hex!("954a72b4ecf47fbf2f5de7a462361e067ae83249720b6caaa8c1cf04640a966ac32fad4d91ab422ada74fa32a3ba7cd3").into()), - PublicKey(hex!("a9fbab2646a27947a7ba8c71051a904e85106fc2d57b56ffb6dcdc152b49a6b5be2336cb74b8d6ba3d049e7fd8acecdd").into()), - PublicKey(hex!("882cb77aa7c1bc68e7f21d53cb74e82454726ac183aa05c8bdc3212dcc5d3a711b9e27990cca26421ec0495caa0817e4").into()), - PublicKey(hex!("aa786e0a23e9d183f2a0717367848a8df113d94eb8c145ab5ea0d909ad43ab9bc18ef079446d1e5b62a45aecc66e935e").into()), - PublicKey(hex!("ac01f1dcc9d410cee5276c3ba20cba3d25b554b7c61e83948bdf6ef9d5e937e6dbd27954adbb8f78568fe3cd02f7f49f").into()), - PublicKey(hex!("b213e73306d433442378c2953a49be43d1902c6ceea796cdf2411dfb3f5f3d468c1806b0fc4763953b1057021275d8ac").into()), - PublicKey(hex!("aea0ca8b5627083bc33e63fd1f980989b599f35fdc61d907e0d0de391d04d05d52d1ab45b8c898f7664869122c671af4").into()), - PublicKey(hex!("85820e4941f753ab46cfb1ea2d8e8fcf27f2f3a5fb192ab791fa1a2c0c7747907991eb2c785dca3b3d120e4ee8f29937").into()), - PublicKey(hex!("97e4fff547ffb3479e7b9c0fdcc516cec5cc5678fbfeb7102cb276b19c370bf8523c47cb73bc458eecad46b478a0f9c7").into()), - PublicKey(hex!("a32163070d638fb8af7f001a629e51ef7300a3ce47c13a20088a6e68a1db8e2964ceb47401a9aef6b1e7cbc596ee0f6d").into()), - PublicKey(hex!("b59399f931378cfbb2411972f8f54c5d29298d845af31fa03e9d5809ed134c170d29cc3ff742b4c68505c929673d114a").into()), - PublicKey(hex!("97ef7ac6d56d092855418869ce161906a317773f333b2c2d5111a78f7c4a8aeadada1210245a97684365df776d77d4e9").into()), - PublicKey(hex!("8407e9ec357d4b0fb5a9dbab4a38fb7ed570d8ed328ac3f1fba87b4083ac3f403a9b63c02582012087d7d5a5691fd907").into()), - PublicKey(hex!("9630db00c95989636e0f50843b42748ea222fc53ca751d5dea0c46969f9b7fd84c694c46d45d712475be6c5b55f1bb7f").into()), - PublicKey(hex!("b18461ce751433ab392cdb10bc8b2f63c82303c8c26b5639c03f2a07dfb71e640761afb8682daeefcf5515ad2eff2b3c").into()), - PublicKey(hex!("99142237fc78b5a36a6ea27d28645bbfeec461a6994b81d036ab46292e22d4e061a1b72924094e3f8602f675435ee6e3").into()), - PublicKey(hex!("a7bd7ac636b94fc58e5b6fc1da7b27f1711d785fafd814c9ddf94f32f9f3de82406ad0454a56f331cbd33c0f8f150c2a").into()), - PublicKey(hex!("85dc3edebc595974378a20f6acc20b68dffa878cd61deb8f0aba7ca3fe8101256883543c5d36ecd2d4cf9289dfc52241").into()), - PublicKey(hex!("90b9e5ab77a8da53f493d464b0a02949e96931f634262824df4a6a6b4fd0ddf7153cf5c7758e370fc71f991691d609fe").into()), - PublicKey(hex!("b123cea6d44b1b0b9523461516faefb97cbf844a5b23f85f97db3e770be554e57f14bd155bf6f76567a3347925ec30a9").into()), - PublicKey(hex!("a6f3a0552e621c5847ea162b80949d3274dfd70a1a1da9b50800ba423d5dc3f868f5bd18fe43db41d7d960fa95233329").into()), - PublicKey(hex!("b6c33a14b54b6129a4fce9145c2aa945996f0a1fb0a6a724cffaf2f7ae2a9de79634f08ca90df67ff877d7bdcbb3e1d1").into()), - PublicKey(hex!("a3f3d3959bb5fc246b98f3a1259853874fc73ec738ac99742cc869bce96da32fa4bfe5a42dd94e0fed2e725168c5b4a3").into()), - PublicKey(hex!("8b293780ca14d26b7cef541ff9b520d038f1a692dfd678747b9233307a423674b21c3ba764bddd7da163c9e782aa7e05").into()), - PublicKey(hex!("847f919e596294d101c9ed376993ec794e1cd736df620208542ff5764214274673985c45b8eab86c2421a85762263a16").into()), - PublicKey(hex!("924c2965788e4f68e3890925926a1a4912cc6f9de44b6011294a28227cd370c0835231e4e70bfe9e32d1a86ebe7cac61").into()), - PublicKey(hex!("a26e6b9ca2582c90185394aa6fbd3cdc1e48908f65b3f996488a0d221f68351ae6196403c6079a31c91c832d078ff583").into()), - PublicKey(hex!("a6de52fe7fe56e8690931ae819697eb0f1baa31bff1c11f433fcc71770ed20c65d92ce8a5fba5c09142bacc4a2fd1afc").into()), - PublicKey(hex!("8032d04c4e75c4ffe9416e3f86daa8a25b9aed4d4d342b63f37b3a05a6ea071506c444c0a1824254adb60a20905f854e").into()), - PublicKey(hex!("81b176b69b8e53454d0f5a3470313ab0c7547ebea8ff371c4fbfa5ed3e65bbf911bf43080c42263f422fa12fac2c847c").into()), - PublicKey(hex!("a646243ac37ba838eaf1693837ff341c9b6a651cda1a98d81fa4a425949c94de4e3c72e505f04a50ac3f6b13efe2aa31").into()), - PublicKey(hex!("ab0147116926a8251f376887c1933cbc3f1cbe7d98cf530463b9f8e6f91c635b82aa968f5a281402e1944123963aaa6f").into()), - PublicKey(hex!("8b822e131155ca08725a0004f0033f0d1b8d538af3323ba8880d3f29cdcd0120cebfc5c9bfecf62b0ca15bcdf7430fb2").into()), - PublicKey(hex!("91a779d0cda4c7293a9a571e3d0580be5cf3a1276a249dfb2d19a97971c4373d1e43885d3b57c7b5021953a6ba9d93a4").into()), - PublicKey(hex!("a918518d8ae3d74c5b613b6f0758cfc4fbdb2149f9b28972fdfc15e20d6eb56f040b4ba068f1730f6c73343b2d2f2240").into()), - PublicKey(hex!("af9d979b3e57394cfae465952f2fd40e40aa96bebabc6d9fc2d359e616eed1c37d9dc4fe8136bcd8e4399b9213adde82").into()), - PublicKey(hex!("84d2a9f0613da5b3b71a482b32b1ae1c18dd173ab7bb85e604a9c180d4428d383cc2238c1fc65c05a70b470d07c7c900").into()), - PublicKey(hex!("958b382547e4a96f41545297244cfcfe0a2ff2a90f140312957ee891dfc6234a28e96538af7d04cab3639d1e34af4b5c").into()), - PublicKey(hex!("b93f016a8b3231a267898bd6fb9e99b1218358001a737a7954745c52c2d6ab330a7444e978293cef887f5c65a658abe9").into()), - PublicKey(hex!("8e4c93d794e8541aa9741241d2782d12ce299ca805bc8a6dcb5c5b7854a05b0ce66d7698d4567c54b5a19e876eb53edd").into()), - PublicKey(hex!("840b08b719f77e5d035a4d72bd44174894be4076fc8b4808b4c0c719e644694313100794e76131ba9c74702708f70b93").into()), - PublicKey(hex!("8fbac2c1a89fd1fe8633b77519578eec86d4162c20259ce36ac4f8fe84d6c9bb2254a62d4a0a9297421a27b096429b2d").into()), - PublicKey(hex!("ae9e9014a3aaec60d134bfab74fc17e1af9d77013903f29768c9852e20767d8f4181694e7792d8ec3abee4abb75ef416").into()), - PublicKey(hex!("995f482157a1a74b4bd353ab200cebbfd8cf95f25eee18cda4bd911278dc9d928a1b7bb928539e808fcd82807cf503ea").into()), - PublicKey(hex!("a2ba63bc93a536714890616178cca781888e2c8c5e51a6601da05802cbb0413d627ce19de639e3d0c3aec08a15d8e762").into()), - PublicKey(hex!("82bc0994dc0195a4bc8ea2e1c3d7c512d74555152f8722d04954ca3bd5103ca714cee3e05fc512fcb61322fae7016c63").into()), - PublicKey(hex!("8b1a1d8d867641c23c650261fceac36b0c4ac54a243b01cdacb3377ed3181086a4e9459a41e927aa0f8125f4c0b505cd").into()), - PublicKey(hex!("a630c12e206f0c99e5140df38ebe867839f2dadb69af47b42ef0eea20ced2214800455570aa810420b7207a0a288affb").into()), - PublicKey(hex!("99fba4649399bc63cba1e2c87065050cfa1e0e13b37fe56fda5b962c9ee96db162614bbe5643e52ac69370574749f0b4").into()), - PublicKey(hex!("8046a9818f890b00baac1bafeb8d44cec8504fcb160b16425f07fcc6e99e03644e974b8d17462686c298417651a7f931").into()), - PublicKey(hex!("aa50676ffd8ccb8be175e217de842ad0238d6608bb2fd15a65a675befcbff849113345a9d5ff083df9608876b5a8bbd8").into()), - PublicKey(hex!("aa41ea68d7777c171e6a185e9e580e8c0686f2c4ab3b29f2c2f56c27493578a7254c5936ebf72149054dc0185d80bc0c").into()), - PublicKey(hex!("a8a314c0218a0908ad936d10f077e0f5dbf4d3de4e8a2a7eea287471d01ba38fc7a549aa5b4163bba01f7bcebcd49c20").into()), - PublicKey(hex!("a1275ecf5433a70872dea93480af81edec088087c9b69d59f65210376cc666ef5e746735081c5cf249316de6229afc5b").into()), - PublicKey(hex!("88bdd7f6627c771f8956d20706a142b79ec8f1db8fbd5430890df0a24835cfb0737891d2c53793d1bd959cf8d97a0984").into()), - PublicKey(hex!("85bed4d7922103f1b9aaeb7a8db8d00079b12aa026b9ba9257ed59c558d57d7b948355559e10af2f9a030eb68a4ee7ec").into()), - PublicKey(hex!("9798b45294c94e5572fa92b932757b8c7a5d1d74b8a5706728fcb5a433fcf088b76606c7d6592f561c959be03ae30fbd").into()), - PublicKey(hex!("ab30d2571d1fefccc95f57af9b2775c66402043ac51f5a6d0aa594b1120a69914b0f10a9a12fd209ab45b677443a9360").into()), - PublicKey(hex!("a4ca8920fc6781b9bb7b36a66cd88f0cd328d7c0ae3956bd8488d2f3513c24eedece3bb98fe2a7318dfb09dffff68b90").into()), - PublicKey(hex!("b4f96a47ba0b2f7e040c6c3d1773d588e086a028de9f1b353b57b46ae1e7df7bf614cf8fad461d30c446d591790e6b66").into()), - PublicKey(hex!("80350ab139ef69a021d18343e1f753311eb646dd8a9b5ca7526311ae3c1535c1b5e633e3af5eb6b6b273a11e6aed2266").into()), - PublicKey(hex!("91a11ea8f7733ca3f5f03225f7b8cdd9485785554ae4dcc7ef2f38a00c819a798c50b2a286c431ea955ce39cbdfcf651").into()), - PublicKey(hex!("ac5b8b64e633aea87f863fdd4459d3b2bbdc0fe198d4fc23bdb19a0bbe29dad719e1e1db39c96bd52654657149e9be06").into()), - PublicKey(hex!("ad86f8229a0ef7f3e487d150ddaf9bfb9e044eab566a02f9029619bd1560e04c0b0881102e69c215aaf4dece3b86141d").into()), - PublicKey(hex!("b6b3566476108d5da3cab60bfed5418f0f27b0c19df07fb5dcca4718adab4ab79f0d2991151ed81046b1ae2bb2eb4b88").into()), - PublicKey(hex!("82f77771c7ec113d9e49c25561a259c94d8f2c59d4a3a12982290f4daf0d553b50d161ad0c2da79f88198cad3865abca").into()), - PublicKey(hex!("89489e1bca1a32a5c067c9776c7ae22c1582a7358a82b43409f6cc27225f6dd25a8244ab428b93c1cc9059fa40fa2cdc").into()), - PublicKey(hex!("b0b83bb74a0845bd81ff671327c0a7157c093aced14e58aa1b3b1b8e2f11fe331578d3f0ef209f829254302b5ed3193b").into()), - PublicKey(hex!("93c7ebe10bcba37ad077aee310a9277bf95e43b95327d00dd4729de05c1148a137e4e4f9cff451047a96c41223a06536").into()), - PublicKey(hex!("b51e1b00db5c45e04f99a0964059316c2c271486c9eacc77b48846a582edce1a39e5016e25ada14133020efc60fe9d0b").into()), - PublicKey(hex!("98b7b90c02549ee64c55a8954355160cb462ff2d10cee24877b48d44a1a6d2828ed4052b42c1ea57716e2eb1ccf62b39").into()), - PublicKey(hex!("a82a6417e78e6af7aed62a633579cedc1d0e9fe8efaa5058b3c6383c5ff0d6ba0b871d7eb87a5634afe1c585a29b64fd").into()), - PublicKey(hex!("a145410b40abd0023fbb9ce82b59787966e7376fce7e1abecfd4cc9525966c49849d9e516b6f762d0a30fe4cb33530d7").into()), - PublicKey(hex!("b4e466bf64775e6a48cf19f562a7876559d7978d244d45c301d5697b35cb7228b433eace510b763f075da80a98271dc8").into()), - PublicKey(hex!("80bea6b7e4e26dc9b4bd1c4b38745e77ed1923560744a54318678d28ab6b47e776be5c31fdf058e8b19f44948cc86766").into()), - PublicKey(hex!("85ef84b1987f1c050a4f8cb8065356d19a484db55cd67498a2b4ca2f72f9a710486bb0d63138654208069029d2777c74").into()), - PublicKey(hex!("af0556fd011d570857d05d93df33864b1dddd10fcd314fa622031d5b0222cacc412a635d53dca5393f13615dbfe16def").into()), - PublicKey(hex!("a7a6ec4c5c687ee1bdde615775086be65d6bb3dbe19c0df80f045a6640bcb0ffb931be1ff0d1205b4ceabd56705b8215").into()), - PublicKey(hex!("aff42d6f5f043109d92412e99c9b2a5163bc410bb63787125ebcc230f2f80a6d665a3fa6301f002ef48158fa855a8fa8").into()), - PublicKey(hex!("b6cfcd44cce581e92a09ab32f3abb07abcc1e5b07bb65fe55f4bc0ceee00d9dc9107736b3fb3951b95d20fa057fd13f3").into()), - PublicKey(hex!("815ba88a2a39a00c0560b7620c0d510577ffdc8e41323dfe5f8f00d71132c092c23526b0ae6ff6681e1d6ab6c3e46623").into()), - PublicKey(hex!("87e112afdca3621452b47ee31d91e6b76f8f714f850f83b0901c1238b08a9fda384caeb2ab64b57ee7122941fcda2d25").into()), - PublicKey(hex!("b4d5709f04600c13b5640f5c6a337655e224600a76b84d3a1f09e92d383c71901813c8095aad0c7a272c9b6719607e0f").into()), - PublicKey(hex!("aa0269238ab2bad3085b1a51c9b461d08a3f9103c53a1fbc3ffc5cc1a657e00476a3e90a1b4a11bdc00444c36bcd0410").into()), - PublicKey(hex!("a9850c0f254301b519a82b4eabb66b3fbfc0a4dd4edd98232aaae8056fedcdffa4ec11b17f0e8de553ed577d69501bfa").into()), - PublicKey(hex!("8bae915ea56b31b1524c4f500dd9eb445b2cfdd482ce8ad12b5736d8ebf8adf124736b868c1c7680c7e9f2b920f09e4a").into()), - PublicKey(hex!("b8cbc0986998d7a2089bd28c0900b4e8b68ade0e7a8fdf9ccf4e244639e141126a2f835a25dfa7980944e509ef3237d4").into()), - PublicKey(hex!("ada12153b600de955318df5a8fc46a51b3fbd7dd681d8330e9830f47f97fb7a9d93ed6ea80e89a7200e4735aeb73a134").into()), - PublicKey(hex!("a1855e95b77e48fbcc2ced2ac9eee236f2b17d204c1e4f3047951307e71ba38af975a9908a025fe5d844dd05836ab24c").into()), - PublicKey(hex!("a606922d4aed12ba3ba4b1ed0489acbe1b3fd3b7b798645f6dc376fe5083d586f889e8fea0470a5b8a4514d7b9b1e62a").into()), - PublicKey(hex!("934df842bc666333fbf12901adfa011b51451ae3b6c04d12a437801d3924e3cc74188cb809fb26e7087b15063c1bce89").into()), - PublicKey(hex!("a759575018e8b94a1f4d2998f951a74f0899e44288e7687ee6518c38c4241b52b94992b95954ab12f4424776a328ee67").into()), - PublicKey(hex!("8804cd0c52b7f7d04c17d109cb3168c5939fa6386bbd178a8ac3e67d43420d8d57779e6a0a982e42cd9ee7763c9afb2e").into()), - PublicKey(hex!("aa8c632a8600128c3380fd46a620be79bdeac56fae0ff877b68aca28374a4b6552c8e98d83a847471a92f74bc9cb6ae2").into()), - PublicKey(hex!("b400363f85dd8a99632ab07ff19ee097885079d507b2943c9d69037de12f1a65b0f74ed87939feaf5c9805db4e6eb808").into()), - PublicKey(hex!("aed74634ed8a1fa181db46e202f1f646e3d6586fe9695822b424dfb0211332338e45c5326ed0c5242ea31bcd4cd435a4").into()), - PublicKey(hex!("a8f3b14886ba06c8ce95c8229480dc87112e0abecb1a8047f90359109e77daf83aca99a56f8e195c2bdc22e3c991b648").into()), - PublicKey(hex!("8446741435af2b4cc6dc30e74c3c27d1cafec49dbbf8b7b41beca2304df84d9518475f24f1a746817fcdd0c3c0875e75").into()), - PublicKey(hex!("91ba3151960a4ada7234aae00c0f171a81549d1e07beda21db5a6f6671c1b1bd3587543c833146f3c52a0fac62ba81db").into()), - PublicKey(hex!("8555c28aeddffdec6a065943d2ecc9de906bf8715a27ef6e3222e89bd55295c61b59da4682c249d2ef70fd20b8115646").into()), - PublicKey(hex!("b9b86e101cc1769287cd6e25b6048c64ceecaf7f56bf4d8b18b15992d8435f288ecd84e872399c5744e3266a9563cff2").into()), - PublicKey(hex!("b28e43e5404fe92b59b9b2dc45ab4cffb4ec143158c9f552f850801083fb9c519a26d1455793359e173962b82a204704").into()), - PublicKey(hex!("af792b54b728bcee179392c9c7c9bc1ef51790141294ca34091da99a5525635fa9fa700bf9a06eba7e1e6dc9433975d9").into()), - PublicKey(hex!("b9bf63ef347a5ed6c083a2b3c9b99ab4e6075e53289f55277215b0687f94636d42e4c937c6a060893950c4bb71033a8c").into()), - PublicKey(hex!("b6eb9484e48cf825a4bd39f5492ba4ba3089784528c6f9ba91d372bdd3eaa77790188fa46f8cbc69cb346e83bf6f898f").into()), - PublicKey(hex!("b678af94bf007988731ccf872808ecc800f64c59ca257923d60116e473629ecd135a8b8b785095e4020600180dd61639").into()), - PublicKey(hex!("92f1b51a2ccf1a8ea328053b07c45b30c4204cb7661cce7a19a23e6abe59c406e9c8e1a39e9d9fd017c0e147ff0caad6").into()), - PublicKey(hex!("9629c3ddc41c5c64af2edbb2253a267991451f83873508adb3e2eb0c8ced6c97bac1ac1903ff0c171249122d34d0af7d").into()), - PublicKey(hex!("8d459177e53dabeba6b02ca2100151cdc30aa1aacbf9a9b5ca1707f5a91a8eb63cd775db119a20b14a2d09c2f0f27812").into()), - PublicKey(hex!("8a5f256046ac918cb9e772d60e6942a76dc6c8168da7208c5644d9d20f7136e4beb089457897d23f8764ef5c6f7cd152").into()), - PublicKey(hex!("97ad6568b0d984987dd27303176e048d1c2c261e9546c19d9b640c85569e4bf608cd321bc21cbd07a86fa5f34296ef9b").into()), - PublicKey(hex!("abf45a52003525ead4797b91ac26efd98f2a8ea95ec3f7fc363d3995ebb9b81a5c45ddc85bf13233af97c27a4a65f416").into()), - PublicKey(hex!("85c87940a98288bb57515497aef45918b8936fc011b6e4c5388b2790eb54c23eaeffc9b2ffbe8e45607f12f87087a4a4").into()), - PublicKey(hex!("b14841eadb8b39c281ebe06979325b3b3fe1b5abc0614b13d3d2eb309a66576c9711aa2051b720e55fb89d59bd20fcbd").into()), - PublicKey(hex!("a1f34467f2a66f70aa293a56562e2ca0d50067b31f8dfb6dc3133150ea0511b5b3851d94bc6029d55eaefbc221ab41bf").into()), - PublicKey(hex!("aae949bd5253c6cd368e7551889dde335f330163809c5ee133d7f7d0786f5ff5cca9eb0ea5516febedd6a0d85875249f").into()), - PublicKey(hex!("8b07def191e57deb39c4453b2ab4b380cc58ecf6541ec0e47664ab0341dc2ac53d8416fa1409886f289aa4e28f26b190").into()), - PublicKey(hex!("a2b7076435ba5534a7101cb0512177afa3f91df9be43334f9bf22b41553c817ded26a06d8e64b37e332c77674cf710ca").into()), - PublicKey(hex!("a8af4db9c46735a256b146c74c80aba945bd64dde94b6a63aa10915179aa1f5ce5a499264aebc2587d9f4aaa0c1f19f7").into()), - PublicKey(hex!("b87e88f17412d8a7e8c13c30ddfe06e3dba913104edbe7ef6970e53111390133678e964c15ebfd2aeecc84f50185f7e3").into()), - PublicKey(hex!("aab006f927006db1837ec7ff1aa1763e3c40b164d2bcb530e158abafe3a84f0e8df77d3f4c2f7ff60312b0fc4dcfd6fb").into()), - PublicKey(hex!("a665363274dfe3f01212c232628bdba79dd8dd0b96604e1a8ebac1c055c6492d92a2de3108336646171a32e0275fc9f0").into()), - PublicKey(hex!("a81f2ae4a0343549b0127020404de368a18e4c65ced68e8fab7d1d9a5200c9f598417eda1f495b6f7e546bd64c6c50d2").into()), - PublicKey(hex!("88a5892f406e84f74232fb9a524dd5e68ddb776af1c782469816213c0d524bd9b52fcd3c11addf7e9ea40c947e1b842d").into()), - PublicKey(hex!("815705fb3ed9eec58837a8cd239ce39879bbfcd2747cc0640a3a1ba2be141826be5d41c19cb2678addafa200ffe3f1fa").into()), - PublicKey(hex!("ad8d05d484ebd47d2f39a20256ae9ae088447c1d3a5c4849a6495c22e3d76f888d5a05242fa1b6a0c7b3f81d464df6de").into()), - PublicKey(hex!("96dc4e4000020e58a76e52165c1a0b9b6a3cbea3bff3b3cdb4c745437f252474b4eada5abc42f880edd3759667a60901").into()), - PublicKey(hex!("98e0c5a4d8222ca94f4e6ecff3beafbac459807cfd011ee988f9fa10d868863944470613ac0b499c249b84e1f7824e60").into()), - PublicKey(hex!("b53a979a9ed42f8cab949a23bdab63494e2ff84f45da49526762100e1d5a0fd116eb1c285e54299555e7f7e782ff3c44").into()), - PublicKey(hex!("afd8ff8a25ff8aa9c038098c0a1909ae3b72d304626b57d43bbe8e3e3d8e92a53101d23dbf831e4b93e4d58f5eeb67b1").into()), - PublicKey(hex!("a9d04d7f023583f7561f8b22b701f5e31dbe12bd40dda1b041a4757a726f335af20cba57ae680ba2154a0ca6ea7dd111").into()), - PublicKey(hex!("afe8e5757412a29772515219ababae549148d270fa608f86f82a33607646475dda25dcee11cb0e2f32232f4c81b5500d").into()), - PublicKey(hex!("883c127751f399b79f3670020a6c7f808305871e8de18e44d3c799a65430a6b781b90f4bdfb294f2b68bdce3cd292656").into()), - PublicKey(hex!("90745f9d6be5a28361a48eb45553a2fe346e725fb08a0e393db48893ec68b47c8724aeaa75dd3dfe439eae68c2c42e47").into()), - PublicKey(hex!("959a5ccbf40a0b10c4fc8e149305542903e0d9656e7b6b75266ddb54880b15beab7a3eb1fd87383709f392b34bb257c7").into()), - PublicKey(hex!("a7e2192ba707a910e4c90814699deb56ef545bb1bce5e5e0028998cac02fc67b064d06a4dd5559ec89dca3e5aaa155ac").into()), - PublicKey(hex!("881e6967a4851f61a008357ef99a64492b9469b76652d1564c346afa044e571522bc9f995ee34eaa4e5364d83852a38b").into()), - PublicKey(hex!("b91e1317b64f3027cf56d0e6b903e9ee49487dda0a3609b16a7fe3a29ec03f2ac1baaf67dfed9f17dfa47bf60a05e7bc").into()), - PublicKey(hex!("80b3d965870071eebd922ce1eec777da1ca8098d4f83daf5d11f03be4bcdc8c59c68100e5f9c35768c18e1aafee063b0").into()), - PublicKey(hex!("90c5aecd8ae67e208708ea41b4ccf1a4b05b969d77a4ec61999a1e045b2cbf5000183319dc83b914798bb108dfd2cdd8").into()), - PublicKey(hex!("8743bf5b781afbf716256f2addc121529bcd350ba0b611fef6cd1f92dd588f46a8183f6714c1d9fd399f53afdc9c32f7").into()), - PublicKey(hex!("9421c4f18f8bc2fdf91cfb11449ae0bf385c06984f1b499cd80d94b189bb36a967879b243ffb50ba1282e2eb34f0be64").into()), - PublicKey(hex!("8a8a3445fbc5d6b29ffbfd5dbe98768f4141755a2c1549ed009296b8f499ed8890058d07f090e39b1ceae61f364c64a9").into()), - PublicKey(hex!("b869ccdb3a68789cd3fdf7af90baa8cfac90fa35eb21142d59030edf9828d52cadfa20347699e292680826aad082b841").into()), - PublicKey(hex!("b91fd47d2d101dc5de1eb990b00c791cc7203cea68791b12c8839018112e0de87a8cd97a99712ca56c57ca9859aed553").into()), - PublicKey(hex!("aab5e216b38776692600c1fc571232fac783a60f84113974d715fcf12dc4c6bc06c05d96481ef00681b697dc9ef50f6f").into()), - PublicKey(hex!("a59f3a67bde19a55281225ba59661519338065d5e0c44fe588d110ce5033f8d32ed3f8397a20a6765078797038d632a3").into()), - PublicKey(hex!("ac85b37849913fba9f92407209562107bd2e873edff1bef0141bc77f99aadf8a5442b889d77f376c17678fc1b5505cc1").into()), - PublicKey(hex!("99a1e78cadc41d96cb84978682fe6e6744c18678a89d35519a7e875d19761e0a1041157d5ded2cf99d0ff30e29f32dfb").into()), - PublicKey(hex!("873d43094961a9bd89823de52df5395d79bc88791c796a6c3d89108b1635532948b5e9500b494650d7afe2de28e7bb2b").into()), - PublicKey(hex!("b1bdffba9f7430229fde250bf13974e6d7e65dd315fad4928d04c098476f5324cc63a000eb19355004e896ca7b503f35").into()), - PublicKey(hex!("8e5d182cfd4cbb28310fc75ec77c96bb6cf7535f30fb747530955c413801df9b9dc596dc805278ab9b6c031a1c8c92cb").into()), - PublicKey(hex!("ae6529b20501c8e61773ee7d90adc826ba1472e1422f04086e01a91aa8fdb4fe45d3ad35c3abffe2eb0b6321ee0be493").into()), - PublicKey(hex!("89b294e76d91c2d904215e704c19e81405627531dcc3df360751f923bf5c132533803587bb1050aff56b20b116699992").into()), - PublicKey(hex!("a7fbc4dfa7c8f7c408ca6b2d74822aa1e6cf1477b070e8ba6a04260f31a8520bd1de5e543728cc6a7c5e11901b89b62e").into()), - PublicKey(hex!("9360f9a5f53f6f5fde8d1710340b72eb82260ff1d84fa26870b51c3db2ac36dc7a15dbcfe07e4417e81a2f5908957d0a").into()), - PublicKey(hex!("ac530d68f0e713e2278fc3553cce9275a6251796171af16802ec4cf8691837ebc4e5542a3e830b66e39c895500d9e163").into()), - PublicKey(hex!("8a748e238c8f549778f1d4af722c5db3d783310f73e8225b26a463b5f65efa1edd367754c75e3e515dc533800a6b3eb5").into()), - PublicKey(hex!("a75cec561d7823397c631b79a690678924ee2008e03c6b3261902be9eb5ebd3fc3ed38af88ba66b03cf53aab2a35ab64").into()), - PublicKey(hex!("adbc4a4e9e1ed119a7c9a8ed77faac0b248a0527b4800efc393e3c1839bd2b83fa8e9ce756bf7fed4ca4f382df7e123f").into()), - PublicKey(hex!("8aa769ff257bfff34f3ee44cc73d0e2048eae356d5b1b2f81962643dfeabd49400d539fa09bd8493b8f14bb56484fe18").into()), - PublicKey(hex!("a951b1b300be4fd7fc94a82478895dd62ff4d25776ec20156e4804664d96ae367e0e3640d05a4820a7cba0ac862b0fdb").into()), - PublicKey(hex!("82e23d6d57dd12ca5e7feef8f867ee433b0245f266e99fd87f4849c26d67e3c0765e130067af01a84b9962e69580aa2a").into()), - PublicKey(hex!("93655168f1c2282be072e2b2d09bf82cdd8e451b0687a79186ac382518e71683a13a1a19f14a7b17f18adcc2c0188226").into()), - PublicKey(hex!("abc552a7731a439d070671071a485e5986423a9c321bc9e0cac05fce7465147df2a830ca43f565900ad672a4c551ce1e").into()), - PublicKey(hex!("9888cf3bd7a63176bed1426a29b69b91bb464c495ece8c50c3ab37708326bb010958f902cc9168477909e899446f2c2a").into()), - PublicKey(hex!("b21040a8f6b93d6d66b8e2032ca26555d32ac3aa0354676efd390048451c1f93abc59133dd726551091d4a761be2fa89").into()), - PublicKey(hex!("992e2e4c957b0333b4ac788a049e729b02e0a0d0dcc895b4025ac2684a906b0a47124ab35f789cabd6e8508a793dcd39").into()), - PublicKey(hex!("96ea908f38a50759a230d4432f76ecc558af18fe3b3455cab0bad5d945b4fa79f3a780037c2d7cba4c386de6a459d6cf").into()), - PublicKey(hex!("95ae803924cf0320713da6372bcec24d3bd98945f8ec44a33897f7218ff89654babfe05e5b54dfb009831be6eb342742").into()), - PublicKey(hex!("8081237e2606b28f7b8337a7326f3309600da35f4acee9917067a9f8b3ebd1ddd8fdb784f17ff3212735ab1391d32aa5").into()), - PublicKey(hex!("96e12c3dcce48dc685d62b137137b9d2c403cf7de2b751e20845ea3c943a4601155d0ccc8e73e5a1c8a3cfe80e221dca").into()), - PublicKey(hex!("a682fac6e393e6cbd0e5b8942937a70411a81addca66cf0332f315d9b43481e8602e1f06706f2b284f3c827dfade8b1a").into()), - PublicKey(hex!("94ce226281afd7f34905faf6d614b168bae84dff1005aa5b7c3323a84aa521186463fdf5d3933bc13952f9f21244c7c9").into()), - PublicKey(hex!("9460cd76ac204e5bacdfd91fea5e9b2583919bc973fb4664f906e2a7df75463c27807c060a7244e3df3ffbc0a212a942").into()), - PublicKey(hex!("a76d328bc1e06c44d8a2eb749ac2406b304bf1fb445c3ca97a57f7d826665897d9d428bb3b78139d5c25e70404749958").into()), - PublicKey(hex!("82f05583db051bd97fe7947c7fe512f9ddd5273159b3b89d5024d092fef6b0b40f8be0ac1a9003be97d62c150b417b94").into()), - PublicKey(hex!("97500a02d6e4c616d900b981670ca2c98f07f4a10b58026b53631163ca91f13244e4edf1922e385f8bc7d822cdfbeba2").into()), - PublicKey(hex!("b267feb51e42c7e8d42c16c3c6ea6ad434061f359dfb94540eb63b0239d094e1f824cb845ffcafa742ffcf0fcead01e4").into()), - PublicKey(hex!("a10d1b551df89406d8056d36697022f9983fc1308b1ff984c2f26f734fca1e0780ecb27d83e7be2c74117c756d0d5e39").into()), - PublicKey(hex!("96480b4d1d61bd77cf02f8e7db51f4adb348006c368c8fe1c08a9fd34847de0056b9057a7ee5b2da64cdd5c86e419927").into()), - PublicKey(hex!("b573dfb42e1a3d7b4e854c4900798ba8e10b279cb6af8f2fc2c050994e4a2bf96e558b9b11ac2b43c0c5ec8d32be6332").into()), - PublicKey(hex!("8ba874d8efa7c3be9f7d730e1e288fa50dafb048287b3819a4a5a36962960dce88e667facbf8e6e3b083da79c63e819b").into()), - PublicKey(hex!("84711948436fa44cd0f93ac679e5e00010acda1a6ff5043bb3fdebe642d07ae697b20f462398429aa0572d553348aa20").into()), - PublicKey(hex!("808be3919570e24a44c4753deeadd3be6aebc90e4b2c9a24434daebd0492ac0f4f6e7d88e45e0ab8633d25831ecc5a21").into()), - PublicKey(hex!("989d217d973a1e67c38aae59629c225bf28ce2de5d6a4815973c17c350b9a67ff06b181644b11e576495fcc505196ca2").into()), - PublicKey(hex!("8aa8f24dd52b0a34f11000dcce719e001e746329b1b6adc217515f5a02f254a9a3c4574b544ae94a97792c8be60cf477").into()), - PublicKey(hex!("844a43318ffde7e63de52d3ad7540eafea87ae5e937f7851132846800e6c58c6b82851832efd6b27749e013d7d4a7035").into()), - PublicKey(hex!("8cb5bfbc261896110c855688bd05bee0f2267201cff868d86b179c71a4df12620b1d08d17fcf0127c394c116e5723879").into()), - PublicKey(hex!("856b504c50b5708e22bdd024a28addd29072b3320873793eebace0b1c8d4044c1f69a1d7060af5cc8e0bd53761f5fb5f").into()), - PublicKey(hex!("98f36e1238b0e2db8143373addac00743f69674717f13616ef3b4237bb4e5e6db8d261f743ca6effca26eaa842b04e5b").into()), - PublicKey(hex!("97574d14055d9d8003164b738888ef1c7fd3e1f0562a74b880765c3af08922c48019decd314483e703079b090e90762b").into()), - PublicKey(hex!("81b7e20f839fd9e2fb924df3fe247751aee84829f7198e7ecec067db9259fa50d8f2c7b21b338074b52086da9a1f7548").into()), - PublicKey(hex!("aeae89c0ad0cb13a2b96da3584cd4dbe0451b7317813dff53d19efa81fe5df0fc0d8c055cb69ce1757c4db9462815d6b").into()), - PublicKey(hex!("b115f830cdb5534ab4ce13f532d9d9eb36d35d579852350c7c3b36f03681895093d1087e6a0073c54094b98310147f35").into()), - PublicKey(hex!("8416cd91fe22f516890520a8ea679fb4ea99138470d8192dc8dfe11583ffe92a85989ad1af524a6af5b59e99554a6888").into()), - PublicKey(hex!("a30b79e8eeb19ad44f831b656f6dca394d04b4db1b1bed512e67518aa60c978fa670f6343b3dd6576a325f41e8c703aa").into()), - PublicKey(hex!("ac24a6b49928e5894d2121765c5e7fa608412f4c4224162a64b12b59d150a258156a3516f07a23893de30753a8be6d32").into()), - PublicKey(hex!("9763cd604e68a4458272aed981558cf5f575350abc6408844d1ccb5e0319e82de38207b9a154fb7cead5b49266575621").into()), - PublicKey(hex!("8322ff26ce9c45b530627fc364c7eef90ec528d087410d517a38617c9851d733f3486bef401958cf1ff3153d3819a0e0").into()), - PublicKey(hex!("86a52637db26fece46f7c857b2b8591534e2255842aec13f4a854bd584281bc0e5602e003276d796452a1204f3659748").into()), - PublicKey(hex!("8894d7eab796b751074ae7951697ea5037ada636b12290b5058a17a4a5f1985bf707834e5b79bc2a4cbd6bb4492d4feb").into()), - PublicKey(hex!("a5aa463e04d74e42e06d68104c38e5c769d2d1f0a244d65ec4c8e3d6a4bd4c60472a3d3131486c2e28211046d994aed8").into()), - PublicKey(hex!("a5d7588997828aa6e4b8c236cb508d9526b7bc45a26b9dc5fe069dab2317465e9461d02b3eff31db9381c8423f670413").into()), - PublicKey(hex!("b26f644687717513ced89878821bb109b296bd7311895e5984e7e00a5d4734ab7f311a4342e52121b916ba1ec9120d1f").into()), - PublicKey(hex!("a1a29e0571a42a379966035002f61276355477da5edbcc8af2b089aac891dd53b5ac2aabc989f02a574a835886080fd0").into()), - PublicKey(hex!("aa081322a0a9f0a82e514af43c508882e71dc06af766f8272b280dcaf7a375483af25477cc28dff8850fbba8082b96dd").into()), - PublicKey(hex!("af305b502236a6f0871f425fbc111ab0d57d2a1764380c9445f10e20c2bf26d5ee26be608d808f0439207610d6b0e3c9").into()), - PublicKey(hex!("972f23ec9c1663cdefc2843ddb3ea94610591d43214f32d12d1476d9a53b4e9cdb78c1b74f432f55c570b110d4e424cd").into()), - PublicKey(hex!("8fa7784878accaa9a723cedbaec88e1655901e5a767bd5d2fed97302e325404c38c0f996fb8be21716dd26ad31099138").into()), - PublicKey(hex!("ac3f8d7ebb4a4724eceff09c69ffaacc3ce0d30c1ca74e8bbfb7055cc8816cbbf26a0ec3ef5b83264d113b0c95b1bf2b").into()), - PublicKey(hex!("977072b253c4ff396731001dd6f84524bee6d22c8b0f51ba23b743845f6829d6fcb4b2e0f28bab5d98ee7a5aa64e60cc").into()), - PublicKey(hex!("b5873dc066716992179574e7041ebaa8896933078550f8f28da4c0993c002630890f4eaa01e49109bb8ff7dc5bd76495").into()), - PublicKey(hex!("b01d6007e4b5f3e04262a7f1b68b128727e045547595068133bf83b103234f73999261f858343987a333920e338c6e0f").into()), - PublicKey(hex!("b4c334609335c0c6202619ac70dede8dbe48407aa32773c031185917699517261c64f440c287da776728e4ccba522438").into()), - PublicKey(hex!("810a43d72ed43ed0da32797513e96ad83cd8dbc27c173179c46d05f493912da9fd60886ff4cf90983c9623ec9d395fce").into()), - PublicKey(hex!("8eb694f964ab8f7a5b668669010c212d13ebf60973fc83590ed75ea635e92298125ce1ebc1a540837f4a526d2510cccd").into()), - PublicKey(hex!("9530a1eb4c7f06735a800f2617671d99945eecd73093f7d3d1a5279eb2fe8764a10d72c97064b9e95dab22d88f329e20").into()), - PublicKey(hex!("a960ce57ec10b5a10db72bf1b344434ffd11c0a073ec28c14a58339049a855c8354d42ae9be2cc7a6a1d052046df4f48").into()), - PublicKey(hex!("80c7ea8581160ba06fba72813607cddf7fef9e66091590be8a924df82acdc128aafd8876023527cdc4a6cfa5f82d60c8").into()), - PublicKey(hex!("afbfd9b3b636db945519aaca512a53696e7318c86c53f1725223ae8c4c0ce2e5e7431a14af24286740b983da455b436b").into()), - PublicKey(hex!("a639260baa2ccdb6091de1c1ee4dca94fd9d905e7a990349f54450b2f8de7a1961566ce64775bbc9279d79e369fe58a2").into()), - PublicKey(hex!("88e184fd80ad8b221ced837e4b877aeb4e895d315b8659e03eeb1bb0acd31692942475464e99e65c17a6cbef8e8151d3").into()), - PublicKey(hex!("8dfbb8d52b5024af356bb1e4f5c5136c4ac9ffbb41b5922cf1437a5599251e8e8c64de9a7baaae7aea29f5547b62857c").into()), - PublicKey(hex!("948bedcc51ca9395dd3db8727d94156c4c1b0f6e03621a17a559162bed2352e2652509e94f9c4e9205707ff7b48339c2").into()), - PublicKey(hex!("a47cfd7a838adab65136c844f3320dd5dbab30d56ccd8734fd8bcb3cc09d0bffc76f066ea8c00a5210897d07a1a08a5e").into()), - PublicKey(hex!("91b9213dec86b9cd9e1dddf86bf371d56c9ef3cf592fce34ad790a6a453fc5fef947be8a52be99e4bbcff27be77466c7").into()), - PublicKey(hex!("af2565f90d414931801dab9e35ce49ada22cca29754aeddf04710fd97d78a522b9a0c387c493bb5e99413b993d594518").into()), - PublicKey(hex!("83673aea730dfea621bc06f9f822bd687534cf7e0112b0d6075f2e94583fc20214b360f3716555aed5fed64c258974f2").into()), - PublicKey(hex!("8602b08f0e643023491ec064ef309f85c3712f9d029362a7410ad4860fcf7af530dd3eb74f4fa97902b203938f59db1c").into()), - PublicKey(hex!("a7f2983314a2364cabcc27d1ea78952e178163ea37d3b24b0eec0d7d3aa8d71cb003c9a2cfaba3b911ef7a1cd24f4dd2").into()), - PublicKey(hex!("830bb0fe152bb173d31713e9177830b5f36081264ce9d7230cc52dddfa81e01c46026f54dadb2b8891e7152881371465").into()), - PublicKey(hex!("95f5045412f4d89c97794eaa956edc9702a86d07959cb5683120095cf396c670d19306ffd829e424b309fbd048b3496e").into()), - PublicKey(hex!("99ab6ea07d2ecaae3c657cfe68b841a35bae7193ef716e49592918beb1515e154d903dcfa1ecee3304662ec3650e41f0").into()), - PublicKey(hex!("819cc3fdb714f327cee4f5198a3b0de56ba85498b5f3756ef3c91f433d856d0cb3649ecbafb8d09094836ade3168d88c").into()), - PublicKey(hex!("99d2c5b9b8f3a182dafff0378bcaa1ac5719f9df8b48d3d91dc8cddcd3b79627303d901d65a35814551ee7a1f91d822f").into()), - PublicKey(hex!("aad58da166d1762210b7323f4333c9598975808614d537109bff5c8178546190daafd29374ac1f43a0995bfc850436a2").into()), - PublicKey(hex!("b66955354e2e200c2111fdf0282e5b502c221119e52fe4abafa98d29e4064023ba6de28f24e98cce3cf39f07bbe8f154").into()), - PublicKey(hex!("aa9d4ab2900bab98de1f70175f067674d9d9ca243a3f5edb498c3d9bf83dfb3e031b32ad4a3b4f8b17079ef083f4a2b2").into()), - PublicKey(hex!("b60711622a689f3077edb91f14aca7145ae092a7f6fd7f9219fbb40b0cf9113d902d83f47a2934ca43ae0f5889460ea6").into()), - PublicKey(hex!("88c5bbd8c896204041b5ad5fb32933a949d0ea8a97e6062c21093fbe86ec094f28e26652debf06dcc1473f91ccc9e2bc").into()), - PublicKey(hex!("a2f79974ceee8c3e7c97dd8e472e319373328448c84bc2c202a34950aa0984a05fd62af4954c8b87e5446ba16727385f").into()), - PublicKey(hex!("b808be5db3c30a0b2ed1a4bdb456c5ed4497b4e39d644f425fa22a9933397214e81e1b53ab658fd07e9c5e3cf7ed422d").into()), - PublicKey(hex!("89102baad133e359bff9906a0ecc2284b290cd1d9af04fb8c5fb0bade6c4a93786ad7070f25ca98594ed5208319e3176").into()), - PublicKey(hex!("b582677e42e27b006373d13cdb92fd98e1bfd7837db3b235b5c13fa5e403b5c56971c54f71a18877648d088ea1d76f60").into()), - PublicKey(hex!("aafba2363b91455b94ef58e22f17080d9f68a4d408196d1d2a16e1e83d8ceedb794c6801c978252ef7a6da40ed6148c3").into()), - PublicKey(hex!("83113d8bdf56d2329cd4e4fd86fed3542e3c7a3c063ef4d0c7942e9eacebc4445c7056809bad406345539365efee2204").into()), - PublicKey(hex!("a0b47fd7d719e756e0e448516dbed0c0464717e6906e40a616fe9da94853612b6f4f043079b258a8416f048efe02da2e").into()), - PublicKey(hex!("b3c5fd472c4905474ea11603b53352d98d60e388474ac2b03ae05ae7e11634dbeed00c392059c1059e8709c6acc41b7a").into()), - PublicKey(hex!("827809c29268505f8e65f1c271255cfa205436415acfbdee4a7ac296de9d63d900b10ab3930e1d215780c9f8faf60dd0").into()), - PublicKey(hex!("8050c64537fc1e2536859be5e4d80a5a5caa079ffeff6033202064f82fb4368c70830737525ba2b45473f87e194bb2b3").into()), - PublicKey(hex!("a9ebbbdfdb64710eb5643ba91a296fb3a518aad43c520a6fdaccac93786ac0e74be1da9eddbba341beb868e47e97a26f").into()), - PublicKey(hex!("816d9f9b48b76c063ec51e030dd7594dca3b951aa7ea6076374d43f26d4a8383d4d2eba5eaa44cf1ecbc997e3851b010").into()), - PublicKey(hex!("b0cc7724e322a130179f6514e513ca4bc71cc847f903155a1b038c661dd2771e9c607bfa1971d9db2776c239b9b9017b").into()), - PublicKey(hex!("a5a59b1b9fc2c52b540ecd4c7013909cb52cc2445357dd2f1b188548fb33e0435194ed5c98c841b1bdc78e173a8c1e23").into()), - PublicKey(hex!("8f76b23b740b7ff1ec2840a9d415b824f7c0ce875118bc648e60ca58efe3738e05ce4e401759e5af44b5ef324d26f137").into()), - PublicKey(hex!("b13e397f736a83630fecc35fb0928e81dd6e2afe38235bb983a3a5e22ec7cc224e6b41a97cb315764dd7e515a7a5659d").into()), - PublicKey(hex!("8fa3cc3b089738506f51248af603ec8493ce24861cb6bc0da24d2e31814f6fa0a288178db26960ff9bf679af7314d558").into()), - PublicKey(hex!("ab5b5892761b2a51b5a32b737594ea01f103cc5ccb15ee423d4429a2e7ead870dfe82d8d4f01b2e9af3aea2700d94b79").into()), - PublicKey(hex!("b8b89eea92e74b7e05bdeae7cce83afe77e9f0774db2396960b4d447ae18af05b0e5226ec7a0d0bc5c332dbe146b8224").into()), - PublicKey(hex!("831300c06f4c177bc2217ff29f02599b89a4d4b491be1057f48f9f37c1b497ab471aaf004efa6c68c1f0cda832ed232c").into()), - PublicKey(hex!("869eb1a11252095fbcebb44bbd66bafce733cdd5c73a19f7f770859e776542c207c1168ead56beca8774b81c3bb4a423").into()), - PublicKey(hex!("88aed32d3b373e98253aeeb1a4e7ac275f45a35edd54aceef07187cd2226b72e20518e783b6fcaaaf5c927da2784ecd6").into()), - PublicKey(hex!("8c5ae22e0620d1bb8c7e61dac818cf7c3a2b883aa55a972e4386469af2c1ff9c7b2738d8ec3bcf39377de49622118b05").into()), - PublicKey(hex!("8bbc2945e007c5e74d37b14548b00abbcb13c877a15c53b41553145069dfe713d6ae8489768eba1f44043488a4033122").into()), - PublicKey(hex!("8e3eff0641a410d817002088daf5ddc01fd12774158c035d35816448ca8b937e6664d31cf130cf3076759859ca80765c").into()), - PublicKey(hex!("850521b159d0a5583fdbf7aec6b5aad712cf62aff79c69d1ac357d261c52c85118d986de750aced9ee7005b357301416").into()), - PublicKey(hex!("b6fc28b71a3422e8ea54e1591452fcc537024caeb0bbd31b685df2d29b9cfbcecd7ad0ff3365a20e288d197e108bda7f").into()), - PublicKey(hex!("98b4efd60a5197e799c32fc27be8ccdce132cc35bbc88f84fdf61b255139a430ffe0d3e1cbbb23dadb41a06013a22f09").into()), - PublicKey(hex!("8917fa01c4b5e52cec29d7ae709425e3db74d6692effdf857af3acf3edbe70280c9fcca6fb5ecd136ec435ba276ebc43").into()), - PublicKey(hex!("a9a06318af61ddc0065da1a28f42eeedd55406ac57b034e5ca861db67e21b507895b67e50ff57f5d5a6cb6ab5ead851f").into()), - PublicKey(hex!("b705b1fc20e7d18d681770db7d70cb382f0a6a3a11efb6200df252a5dc5b5ba8a3c02428325f439128320f64c11d1e37").into()), - PublicKey(hex!("86e625fadecc7a851fa55100a99eebc3f6cc9b343e706157ec6f9889eb570eb9c778d3d9b09a4f776cb1533f247ed5d4").into()), - PublicKey(hex!("b456e53084a2c16af3adafe492af7403b9da715abae50a32e3c12106ac8b62a86e5227895630caa7aee9bef09ed82ce2").into()), - PublicKey(hex!("b854b180d9b6a0e3b6d9bc1e6ea753a4034a3e7257ac877722a03cfc8ad1352189b9d80495cbe1acf57faf3c6af736e9").into()), - PublicKey(hex!("847d8afc70b99c7a3415a6b1e12f63549a662f155a2c7600ad7ef58a7695cccc33d601ef8465ab4fe9dd45b6116273ca").into()), - PublicKey(hex!("b8ae5c4d86c9bd469279fe777a04813eb841b48e6704be419be4e5714ed925c49a03e4d531918c3234c9b83f0a9dabdd").into()), - PublicKey(hex!("a5a845f478fbe1b4a65c111c3dafe048200cf68988278341c05329a18803e926f17add469e34622b69773548b028343d").into()), - PublicKey(hex!("96d4ed77545e25985b8d5d07762a548e1e83e69f6ca940ae4ac70031c979406646ad724a8b20c7493f340a686b4206b4").into()), - PublicKey(hex!("a8b823d4aa3635746feed04b2a7f852359e39af75c7da99b08784346d43fbc7e62da5d94b853c6407e5610321cff211c").into()), - PublicKey(hex!("a4ee2437e0e39982a3d20c53aea2137ad474c577f1eb215f055e340c1e4e722ff021890874c0c5de3c44ec9f57c4f4a6").into()), - PublicKey(hex!("917e704591d38cdb2eda70f064dfd0fbe3e80d0ad9cc2ad514c674f258c6a589609e5163cae4ebccf9d3463b1fe1cace").into()), - PublicKey(hex!("82fcdec7c8df977d89fdcfc66cad099c5df5cf8cc4f2c57acdf87f8f60f30a6715054b55319e56f27e896cc33b07dd4e").into()), - PublicKey(hex!("844ffde9768ec0432b00168366f23159e92ce7ac7b4587f65d50a011447b71bec12f5ad2095bdb04e5af933822b32bb2").into()), - PublicKey(hex!("a9b855262d4c32dd6ae0f7350a1b95dc4cdf0e08bca8cc14a3f58b2f49653540a9725df513bf57dfcb6efedd8c60c434").into()), - PublicKey(hex!("b417292b88d5ea0dac1fc361cd3597ad4a613ca481a702c034a04797e2e7b8e67b08057df8be7f2c014310728055234a").into()), - PublicKey(hex!("aafc0b9636bd2c8cb2988984e355b244e69ef81d7f02b2d00a71556a96b8e25210a2d3cb0bd0977c39829750a2c025dc").into()), - PublicKey(hex!("96e647d8278c87c6a2edff20681cc87731f8f594c305c4621fd1ca007d195b2a4a081850e9d5720a6f8c4e71d4f4c1d4").into()), - PublicKey(hex!("90ee25d10d400fee5f9d0e1f53a194985e7c39a9a90ed760aae850114210d653cba6d0ed7dd8874da7dc3a4bb4a98de9").into()), - PublicKey(hex!("8c9f0e64d1c4b6deddbc4b87e27d45d24135655bc125b5fdbb07ed226f6f3398500a6aac5ee6ef8bb7ddbd7d15f049fb").into()), - PublicKey(hex!("afce2866c197df192a9e1e2ed35d11b72dd6af6f2d5ee569ec6a395b1d24959a7fcdedee86f6e61a2aaf25f9ec4e6287").into()), - PublicKey(hex!("b901423e7f00267bfb95d656e5d031e31eaf010254eed449d04a1ea16fcceed3d88bf5fb1b905523972c70111ddb9c19").into()), - PublicKey(hex!("84ea93629e0a08d5f1f7b78c6e8fa8f349f8a41a45bea578232b2a09fae41310740c899a8690cad9eb2fb1869c1ddf6b").into()), - PublicKey(hex!("8d6dbbf76d38b60db25aa7610ec09c2acd07b28670fd23ce4525a59e1b6285ac7a4ebefff1888520a0727c48bb9f7725").into()), - PublicKey(hex!("9953871b114d2668fc42ade7df3b5fdb3518e9c5edee89cc26a996bb8e334a08210118238cf58ad1df6af4313311cad0").into()), - PublicKey(hex!("92f3e734a821a94a17809816ec57da913807cf519d3531d77a1a2cbc87d1cf38d7f35ceff7672e2763a9f15401574b80").into()), - PublicKey(hex!("8c8db581951bd429c9f89807b3f412cee89b64b48474d56d58ae61969b9e99d85ed28b67bd1260fa484946b0897576fc").into()), - PublicKey(hex!("ac272379cb0ec338155d82a4a46a0b617d3e0bdc0332a674d2fdbe2ed864262d318885cf4f02bc70ac3f8dd5aba760f0").into()), - PublicKey(hex!("a1a97b910f845bf4e53799b0b5cebb7fe5f23f4642b0b1b5f2d91cc646a4fd06ee5b1dd47162367f004abcd11c88c6b4").into()), - PublicKey(hex!("883f1598b4e93d4d62e2f1cdc5c2f1fde6f7a2564bfc1a7525f1e6ac23ea55c1e1f08d6ffcf0974361ca6e0cae124c75").into()), - PublicKey(hex!("a5da8ddb649b34f97876db97ce7093d9ff8302a597df9991889640581e937dce5520f627c25d06f54aea61c6181a4617").into()), - PublicKey(hex!("90a7b8f4f7733ecfd9ac5cb3ac50f099fa64bdd58da115b829ed3a7ad44903214d867f9554fb0649183109a648b1d1f1").into()), - PublicKey(hex!("abfe409b2dd4f3d5c128a84d702bb5557bd947a6bfe1df0de4eb8583765f930ab463be6824d8faeeec4e336a85cefc50").into()), - PublicKey(hex!("8dcf4b90176908f2d4bbadcef60023a7287ffa1f6ea9a489e8aa5dbab2528d69115e8188e0e0732944529b26261cc5be").into()), - PublicKey(hex!("83176c4e029cf18faba49bb29a01b5619f35487257629f14641d48bfbfaa2b281e3acd3b20b874afaf8f5ead4caca87f").into()), - PublicKey(hex!("995e7da9f84ec5f2f06dd5565cd8e1dab076bfd4fbd81c1fcb4524b5aaeb69444c5b244a0edc882daa82053f3e91f3a6").into()), - PublicKey(hex!("97f9104594fb2396206bdd28fa3494a60f39ea388515b614438d431bb818971008909a53df8dac673750293d61058bbe").into()), - PublicKey(hex!("8d4bd33101a0d3140b5d9635d365039343a53b756dced6f220f283d6d34934f7a72693ed8763a911a24233d8fa574410").into()), - PublicKey(hex!("827e028c39da0db7f2ec8c5354caa02c85d66c2dab73165ca8f69de3e24c7588703e340d799fd4ca7fb861813b2b9b22").into()), - PublicKey(hex!("a664423e7b42695b5d8a103535120afa07c7571641053dc9197e039b53e52ffcd73c91267342f3c487884f7e03930dbd").into()), - PublicKey(hex!("b3ea5ed13cad837179fc5cf68392b6cd7aa350622e61e9ad7b9ed2edc688608002d15af9d167334b41030df2ae49b6b1").into()), - PublicKey(hex!("8943ed4e9040956ecaff90e068148bad1148d851b6c837d1a27ed6d199b6f8e2bc76d778d4bff65008d4a5163306a638").into()), - PublicKey(hex!("83446ce132da2bff6a0768517a7e8bfd50fea784f08f5613589172568ce6030eecc450b82dbba91ff394a409871d39bc").into()), - PublicKey(hex!("94c0f309f0553738a6bcbb0e2c5531217a4271070f31cfd57932a4a8ddd469d64e266f501ea39a974d6aef9bb748c8a5").into()), - PublicKey(hex!("8e5302f71fff61ecab45c2b3f9bf40ff54c73277ab5ef88872342cdc9069fa0a7ba85bcb22b3ac0b14db6e415de80eb5").into()), - PublicKey(hex!("8f2cc48b400ad6aaf8b04865cb3560e370944cca1a3f56a210858f5460d1d1670e88e1cf02c5ee0c6d447ca514044922").into()), - PublicKey(hex!("b6aa597081daf781516e45928f8801a4e5b966de6e1dfd7484953d949a47eecfe32d0459411b6fabb4562c722666a9e1").into()), - PublicKey(hex!("8cf02871cbdcc49ed5b2d35e511beb435408d304fcbd5977ea530a5868f4dda9f3ac562a26a4e121c375414e72493c32").into()), - PublicKey(hex!("ae6a21e1899936603890416562fe331210bc76972666e30889fb478daa750a9737f60a309c5135f35305621be2275d8c").into()), - PublicKey(hex!("8f8b7fdc9e0628d27beab637b3d9567f0971032b21780822271e05e1207c229001ba0ed8c21f00d3a00c842ffc89f111").into()), - PublicKey(hex!("b377717e41274615d5695d2950243815975347517fdf6162c8dd1fbd2f8e4e501acc836ef7da663fbf3a3d58ca5970d3").into()), - PublicKey(hex!("ae7847f11a13d8d0d963e36f107e5c62c5417def636c5a9dc4c4a152ee6fd7d5c4e3fd3c58d04860fff49d5662593533").into()), - PublicKey(hex!("8136baa7f2be7b5d7a614b79e758765bf0530b775a50cf3bed866543abce24c80366f306f83989337fcc07833de4dd9c").into()), - PublicKey(hex!("b2a4daac57e91f306f1e8848a90d40b618994206075c684e5e99052ee57e69a58dc7d724de69dfaa9155f85beb10beda").into()), - PublicKey(hex!("883f24d44c1ebc8216ed9112e028dbcc24fe7b2b4e63ed883c11d622f01f3d24587a51a956fe9ba63ddf2147cab099a0").into()), - PublicKey(hex!("8215479e70e2db2437c4676a321200fbc376b1af5f8db042800ea84f54188077dbf11e62bc40d2557b09f1e29bd0632e").into()), - PublicKey(hex!("a734da0e7238da01b92ab746900aafd7c109b02100d5da15fd1b1be5519bbc3ab12094c7453cdd9ed84080a4e6c27911").into()), - PublicKey(hex!("8f81da74f90275581520ab11183775ba53cf9b4aa2913dcdf8b6f7da0b9e9ca6a9f434852a8bbbf2becc4533f8f837bc").into()), - PublicKey(hex!("84f3fbe3d5dcdb6dd8f4651deb9c64ac4a37bf8307472620687e21b2bd2729a00d5c01eb0dfc8367762509bbeebba8b3").into()), - PublicKey(hex!("8e30ac7cf94d001d54c87e6019c9a52fcc48ffda30f30f50f00b6a6e8a9d556dc66f38c24dd04f32855f5b82931ddf02").into()), - PublicKey(hex!("84aa1c4753031aed06b4152e8747774b1fc2e1445d427c715c635ae61332a97389e74f82431e9c32c8926c96d90d486f").into()), - PublicKey(hex!("b2013d8544f52f0712f509921fa14f570800c0bdb6d0bcc3676a2d0b088bc5b037b17a6403af95bdb278c653e6abd81a").into()), - PublicKey(hex!("a08f6596272cc5b9f31ed03bd4643d1ab6d81597b97bd08b4eaf26d5b88ce7e975eadddc052e3c8356a14cc969d729b9").into()), - PublicKey(hex!("9008e9a281ec8826660727d91f28011f773c3c67b94149ca87319b4dbe8b3b1e119388abb8645fe7a78e9c753d77b68c").into()), - PublicKey(hex!("92b6d194a8b9dc6620307d477746f5999497f88603b6c34810fc2211aaab8e83fdb558260c8a412b83e3f76fbe02e66a").into()), - PublicKey(hex!("b20808cefb8c9a4f072deca89227e5e062c4e9699eef9d1b1469af34bdaba32940d3031ef8a9df121fb8b6583bcfba95").into()), - PublicKey(hex!("b3e54b420193693f5f72974e0a211cd6c444450bd759a0c45bd45884a5ffe9220fb511b5a5cad9d8c06f7b3261ff274b").into()), - PublicKey(hex!("a49c01757236c8c479f67ede70d6280442e21934d0238ed43ee32ea45cc92bfef88e9374eda24d5b5f099b4795e12aa5").into()), - PublicKey(hex!("9661c848caac46b077a7ddd315653fa63cc00753a7a5c3eb37b9320b0978c529fd21dfef3eb6b210cad852a625817efe").into()), - PublicKey(hex!("81128b906a5430852af88b7031331112c1635b8149a8ae23254093aac7e184dbdeaacea813a7db37e56dfb383ffb4f7e").into()), - PublicKey(hex!("aac616e94d1e5dcdbdd304d658b8cab30efa6f9ce09a017e9a1369449c370a646af810c3796480a71877b5ba207f57fd").into()), - PublicKey(hex!("a430abee01d609ba5bbebc03c3f35eac287f6d0017b772873ebca7abbcb4b0de71bb97f0e6c8a8f7dc895248b4219cec").into()), - PublicKey(hex!("ad5b0a19ca0c91570a98d9baa03c95b2547070bb4c9b0ecd0cb7e03611e6078dd08c74bd4c0af27371274bc37d797679").into()), - PublicKey(hex!("a0382a948e776cf79846e6ad6e55ca349ec4ab37ac73d330240f832aee60cddcdc3df59083eb64bb2918eb19057c5b30").into()), - PublicKey(hex!("a1653c5477ed2d6c1ab9f1749ebe8162845622eff4a5c62924c729d75bf2f1bf726dead3100472592ab97c51c7c6c377").into()), - PublicKey(hex!("aac10f3e865b243d228f47d267e557982b0cae86356397fa00ee9c6737072d206bdb80c6b73d7671eb7d0bc9ed848d10").into()), - PublicKey(hex!("8fd577ceda8df32f955e9f923f018c8d89f566a35dfed17db2f935561896bc2038f285632344517850104535b004dc4d").into()), - PublicKey(hex!("98738e1c4e47de7eb26bc5bbf03d27dfd6c9db64a760f61b5b002c0a1d39735f0576ba7c0de6423c6094cb525c2a5526").into()), - PublicKey(hex!("92bc528520106ca6f0f03c326eefd83c6c1a8f0cce6bda4aeb085682b185801f821a001a8832f3eeac1351d88deb2b24").into()), - PublicKey(hex!("a1ae3ac5fcae99769c4cfcf44fd05b745af658272eab42171a7a56d5e4639449122561a10c33d3fe87682eb285c902a5").into()), - PublicKey(hex!("b8301ace0eec14790c69138a3e2abf832ecd19ef51d53e9a3533c22c7395bff527b924cca3bbbb68e48a05d8e10d2d03").into()), - PublicKey(hex!("b8550f77dcd382d38199aa57deb198ee70b7a7c191c42792a6ebadbc42834cbed59009c70bde1efa8d5b8d416c6fd165").into()), - PublicKey(hex!("a8eb958090ba78e105955e035b1efbc72323425be8c9ec7545a09a3953482958036dfcf234af75fd80308a2f88849507").into()), - PublicKey(hex!("b92036fa047de39e78beb2d1012e758b5e8b37e840e7f95f2e2dd6b1fc3f0c38421c8e0675e941334ddaaf40f63bfaad").into()), - PublicKey(hex!("b56e42e5e8e37de1298bf16b0985c04f0ea06b1eddb9599f8a6241477e86db8121efdc7b6df94bcf8485d1f66105c3fc").into()), - PublicKey(hex!("88d916225d642b5df09715e71e40c9df6e8cc81d6f0dac19b10ae959ae28fa24c127f6a092c6a3a5a908fdf27d7e2f77").into()), - PublicKey(hex!("8ee3ce0081fc1dab6de187d95386aa1052c8df23c5aeabdd5b49be430b0bf41f2265078c8a9c5efc3ed93e9e43f479ef").into()), - PublicKey(hex!("996aa87cb94988ca3cc7d4d60a3ee98a76629ec53469cebfebea77656be602f5c967607c7f4cb619937e54bbf204b5fa").into()), - PublicKey(hex!("884c6357631a82dd8a6066fbb10e0b8829c3afeb2a6fb9beac0275c318efbff605ad11a472949ed7d3c3870ca7848cc6").into()), - PublicKey(hex!("b33d01bcede933271a51d0328326af53c787dba341aafa31c219beeeb90bbbf73f7b2184222e6b85f8c780841840d31c").into()), - PublicKey(hex!("873e0f1afb2d5190d0f2cc9287072fec1f4c385172517153098c9604d5de425a2a3280e3a7884c6ea5c17cd28d75ede1").into()), - PublicKey(hex!("811277087dff3e3d12a0badb6c47fefa9a3404be343c825b1732675b9b56026d581c72b82759c64d5a2b6b58efa9d221").into()), - PublicKey(hex!("90c00fbe0cc529bcaf31757488a00a4548813bd3101254dad824819a69e2fcd9df39684ffdb25b46406d35de66080ea3").into()), - PublicKey(hex!("b31b53d46ac3b917dc019f1676236e283ad579c7c6cf4d855fe84cc11a5af64b2267c00f7682d34e4939ada56b8ee472").into()), - PublicKey(hex!("940b7d2d0fb1c51461d325413b0aed1ca5ccb250225da7b73a4356c015f243b04f26f19d4eff69fdf34f6c5d38234176").into()), - PublicKey(hex!("92cc69a2ddd1927a202bd32a3dc2c5013832caa0255447bf093718c9e3b8e4f6fb4614a413945570075878d872e94a17").into()), - PublicKey(hex!("862e3e58502643407e60af51b6b59508af13aefd35d2c25164c14545159a187551b99eebb451ece86141926e9f0a97ad").into()), - PublicKey(hex!("847892e2c1b78b37abec4c1be99d50c5549f1f9d133dfcf2fd19fcc0e79f6642279583f8cfe3ade58030de16ad739d70").into()), - PublicKey(hex!("b34e630870646a9a7115ed17a04dcfa8bf1c7d682012faa0246924752d4ee69608f246dc93cdfa9d67e64039cadd88a3").into()), - PublicKey(hex!("b3ddcbca1d25d3e79c4dd99927387ceddeb502799ebfb3d3013b9b1b12fcba8b4019b9ae66385d1a6bf6a8531f29d889").into()), - PublicKey(hex!("86156644b162d2a08701093207c3db3a5215c3fad3d68390099026d72f81cdcb2c32c597679774d1eb062dfdd2d17012").into()), - PublicKey(hex!("ac98d20d2ddbf9a5090de3070ba819a6b5373634d05284cc8465232e16fbeca6d2c9fb18108f5403eae84ff672877ec1").into()), - PublicKey(hex!("92abbd517f3c272eb3066ac3b1b13f65d72f629eb7472c626222521a06b3bde1c83f0697d91ba57b913fec3bb3d62121").into()), - PublicKey(hex!("b46713590d56cfaf609be10a806b5716e66474178bbd7f4eda2c851e3ca15db93daa4a6b0586580bb7620b4f24e76bb5").into()), - PublicKey(hex!("a10ea0d855f6d2fa3c3930b025a0018a04512d4b7f8738e45462f4d512061a9751926f18b5694ce71630e02486e105ef").into()), - PublicKey(hex!("ade8c2670394a8c4301c701a60490400a0a6e102d0ac85ea8cbd18cc7318378a2f78dab403195794ecd8b70d6188f5fd").into()), - PublicKey(hex!("9307c8b5e1629ef75446f5d7c113a532a178634ac5b6f1104bbbab90e14af25e1ffc50c9d15d62a1047edb8e57e720ad").into()), - PublicKey(hex!("89e32142a5f37c579c95789e742f66d941a5c3b0aadae810cc02985ee64456f3f9830addb60de4b56b71a7f3eddbba62").into()), - PublicKey(hex!("a58d4ff293677af4d0fc1c577a77675a9072fe7fd42621c2713f0a6455d2e72b0eb68586da1ea83f1a772ecf036ec0d6").into()), - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("a65ca267854f7725ec07e57782c3f41035e52ea68a909a9d2d36ae2c082932ee0dfa8162e5a3145f0263453abd5b1ac6").into()) + pubkeys: [ + hex!("aa10b12277616e04b54c1890851347b31be15bf4c12ffae27865cd2ca6c9b9506608b06003cd0b2bcdc407dc2a231340").into(), + hex!("89f6a874047f9cca4cda217c90e461dfe8a91b298554090e2880a22806879da585fd6de86d1d6c52a59b07a15c64cfae").into(), + hex!("a0f7e7e13048b9953dd57eab7591f725bf70b4ef05d163eff09702a665aeb7cbc350e37f6803a42095167bde9a8978ba").into(), + hex!("b7353d4ffdce6fabc3df30a5fda41ccfaab8c251c131496087684fd1ddeafafe1b23aaafeea77796d320a5b3a07a77ea").into(), + hex!("98428fdecac17cbc38e092b034c5386e71e2b4806410e46a5dec71eab36c91faa806999319f7e900d432d2f8cbd34fc9").into(), + hex!("8bd4e1dddfa7f95991f2ca85024e70d455de2d63a97033624ec266e48ef580a1f4ec446a34ce0eaa905d1ec544de98cf").into(), + hex!("889305e5eb4f4bd4760a51d587bcdb28742c3beccc52a0aa398929b57e43abac4c47c6fabff1cfb345d4a245079ae02b").into(), + hex!("ae8afee1125fda446dfda84b389acba0bc3b840e237be5b78f388f43c09480ea3d5f69d2ac9796c706f443889c6b0479").into(), + hex!("8ea2b9beaa89dbf9a5ba60c4c97bfbb91c49cf7674dbea8e0972ba79aff151c0587ca46355c6bea53dead0af5186d92f").into(), + hex!("b9cfb198d16afd865b81791f4ba612af31216e3a6adabd37399b28c880a1995d6c935b4c8a078802e371fa7081136ccb").into(), + hex!("b2a39cedeac0ab3273f40560082df9ed9738303892d0d9705fb21e23e2d62e1bacce1734d2571c21b80ba992de68a165").into(), + hex!("83c8701f1bd6013ac09502b973943fd23143bc2eb62068b2a0b4c5c87cf8f70d4a70a05927e0fa8cb531b6a0393428ec").into(), + hex!("97067f80c6a90595349b903021da1b1590f026e10fc9d42440bb6dea8b242c995c2d1a904766fc75e32cc36f2c0517a7").into(), + hex!("9051082aaed9467dc4f2e458a401fb71a6fd3a709430df4585cce8b04d47bdedd751fd4fa50094b10de9a33cdb3ff41b").into(), + hex!("93524a14ad77681723bafeb9a9a376283e5f3591acbf7bd3b08695bd79e3d0daea6c47b83baf4dc54ee5947276637900").into(), + hex!("8724e0e971d0da871974bf116f3be430ab365712818e45993fbcf73d223d6d9b8fad5c67d680feab4ed1a503fdaa3520").into(), + hex!("83a950e236b8e4f977eb39d8a6c4e8c2bf6c39d189fe1cfbba9627aad0185e28355b8154d0b6ccbb6671f3a9b005585f").into(), + hex!("82484dd8925e733f6a4b270267a28a42724629e9eec292ae7d916a3b96268293a728ec56178d5312367afdc99e761674").into(), + hex!("8dbbda27c58a35c166ea8f5bfcfa7e29736bb0f70f904a825f583aede1179c3f84396df96eb1c6581143f6af6c546456").into(), + hex!("aee74d86900a0f5d574bdad370474e29d3542bcf80fec415773a760ad76406e11af6cce57415f19f4905597f3ea626a5").into(), + hex!("8127062000d519c88fd55e990032ed1011c16f8c98879f7f48c67965326b89564ed92b2d25d1767d098ac197d7b46ab5").into(), + hex!("8d34fd5aeb4081c69008bf6ef1d93a457ff602260206479dc90510b0bd2196aa8af9c81be124c05776af98b520deabfd").into(), + hex!("8376f851c0522225a9304dc5256fc4326a11b4aa0b1caecef0107bb03196d433a3386c66fe6de6459b7036229ebaf2e7").into(), + hex!("b87b88814563fdcc24879237c8799853a41032729b586c7018a6200f589ec2367bcc845449def6036d5a476506c54914").into(), + hex!("a06155545e152ed95ef87d19c9afd3694e1e1d65732781f385f2b75780661a50adb5499541f6f87e97d6483ef763e538").into(), + hex!("852a0bdf07614d90e4830a2be038466c6109cf76e38467229f6db09c3fdeffe3884588a26eb54d399daa8c64077f5ee1").into(), + hex!("ae7548136e5c228994a6589e8aa4edd58532b1f5f8a11578345103c5b54af32a1e481841ed719000bfaaa510cdd7f1ff").into(), + hex!("aa994095d3a6fdc739e19e312452f08b0221484bb2a98c1a365859157ec454c52e22c812a8ca331fb1bf037482a5a325").into(), + hex!("8f1ad2801414fe75c37d87ab6798a617f6deb791f72ba08ba64fe512b26ed5c72a84a5c57c07bb31bead1c236a698116").into(), + hex!("8326ba55bd7d8edf114d8bb840d8212ddff6c8c4a33c86da11ec4781f8a4aec71fb3bf0e44ff4348a2af3233aeb9a9a4").into(), + hex!("85bb0795baa8c2c7123243b749a8d71a80108d4d197bb1fb63f5a375a534e9fdf02c5e729e562a8520fd672a93a9b25a").into(), + hex!("831b11ceb6175bde7a2c532552b935e18e7741e2c93f747d8efc37261dcb4278e8deb88a2cd33a6011c22ca9028d44d2").into(), + hex!("ac92a37a0f7d665ef778dae08d9b7647ef9736ddb86b808cf8c803bb487943bbaf54eeae5671015421abbea758373a89").into(), + hex!("abb177d8b257310969ff65c954324eadaa6b989f01c4bb7ae6b14fd396c5c3106b05e7e5a6dab0a866afbdda2142656d").into(), + hex!("b5603023eb7ffab692004b8c39c58b46de413c39ec86fb1dcf1709d246bb7f60363ab711c23bd9bc3fa39baf2f0fc552").into(), + hex!("80c2ea7213c89c5fd01e3fd6cc7d74ccab278de9cd6065b42f3bef8ebc77c49aa4cbe741d9117afd85f0d675895ff0ff").into(), + hex!("ac9c0f11c456561b26d7ed72391168fd4d7d7a3b2ec3af3d89cf61c804984e239d5f090e73185d4368a4d1c237574360").into(), + hex!("b96b4d078b6b87e7d1cfd58342b1816e1cb915d9ead3307c2751f72796ad003c5824bb37291085d2a2451b4d5e2213d1").into(), + hex!("8e3d805de69cd4f81b9952b25ff65b0790f103ea91d855e5ecc97586e5119078053e2bf4acb60d5a2c9c608925bce539").into(), + hex!("b6ef3efa283b54dbb8e4a24f715bde06d90a12b7e86c260124e3323b3b67c04124ed3da23d99f23d31e050eabe59452e").into(), + hex!("ab472c2306bb00fdf2bbaea1dc59e04b96c9dc52cec10d2a37b2275b79678fcdb4f5a8a23ed6e1c2e10d174669358998").into(), + hex!("a83206310324ae9a56c35ddce6440abbb0478a755954d70024f7cd26a80fdab40e462cd361009f98925c9888cf12f3e5").into(), + hex!("a3d9776f078348cf2efa9ebe2b7174fbe1227d70af24deaf2aae0bc4e808b256cadf2c35c10d27b7016142b23a8b5c5b").into(), + hex!("b40cef0f8e65047d0607fc331d55436477c6024deaffffac38ad4518b79e6ca0c33dea4e001c845fa835c032ceb24a8f").into(), + hex!("aea4c67822c5f24a3e17685c47e19d9213b763eb613734e128c2170ceadfe656fc3bd782e75396b968518832eec5cfe7").into(), + hex!("b46697edf5e58554bb9f0a504efe4e27abb883144fb3bb02e1b3e60bd23cd1878f47ed40e0569ec6485d70ae156fbfef").into(), + hex!("92d97bf88a72b34824c8c406265f166e59e91840272ec9e51616b0bcbb579f371814b89f532056e95829d4e4b28abd5b").into(), + hex!("85929bef887e0ceebfc3bdf733448dc8070a484e2bc89bfa85663a0b30edbdaaa785b36fabf6d2ed01b7367a99761f94").into(), + hex!("b3f330ef59df39e9150ee3ff6bd743c9e5703744e2663b7bd6fed15a150d866b5b61183045aeaf9885f62764c9a1e64f").into(), + hex!("a15ad89715d236b062878e75cbf8132c55db0db3f65ae0768f44501c0bda9c588b32d063f4be4d7ebc79457c58c561c4").into(), + hex!("b43e3573daa78765e007ac63c3ba06f65dd1de3b6946aa835be4568866ab802842e7272502f208d0e99e1dcac782da6e").into(), + hex!("84e02e4ce82d96bc3740c8aa00e1a8fb7801ca9ad1489290d636c20073ddb0978fa54191d8daace4032b92c8f0b85d5a").into(), + hex!("8d35f1c0df64ead05d55ce5a7d6160e711d4e7460b049638c2bc2dff3b8bf879e1ef8ce5ae14d029ee43eae9d5e99ea2").into(), + hex!("8c2f24127ef6b4b6d18e18602cb146ee8c7d4d3c031d97d94987ce5291367ee344f70c6784d55267bc6d646f3b47a934").into(), + hex!("b127067473276cba846054c18d6ef4eea1e2432b6d3d74624340c6c5a518eb6998a09b0a742b27a7248f0179ad0a6f5d").into(), + hex!("887d21a5d456d0c52ae3387163544791ea032756bde11c242c56e378f03d540c308a9dbe75b003e9f160e1498207921a").into(), + hex!("ad9b4f0aa75c6df3a0717552d660abcfc6969526b3733a1c0b7e74a4214f255698b2c981c658128757ecaebddd3e9847").into(), + hex!("afe461e86183e7ac6dfbd6e0dca8425badbec62fe9498307e685ee3d19b608fc203032f7fd7e844ef299660f1568a97b").into(), + hex!("a52a923281c74043a12889166e6cd5251c0845015cea25c803c99b5d5576deedf59ec38bd27e3edd2241d95ebf1e58ef").into(), + hex!("b8298341fe9d74ff885be48bbe359aaf434567c701cb12623ab186ac72f591f518b87e87bb2123789d810ddb73d45c92").into(), + hex!("9882282e1aed4adc319f6d23bbd1cfbf0a7b92e8dea663880f23d30bff0021d381138f7d949addf973bed505183fcc8d").into(), + hex!("a56219ed90a4de900443687a85822e5be66cd864c480dfdb06302d6d4c1bf0c807830575df04eb394c0c4e484349da1a").into(), + hex!("b80b6b57e35474b08196557f50a7f8c9b9460613a34a933f269b5b051bf1dfdd195c17f5fc49bcd1014e964e01ed65bc").into(), + hex!("b8c4afb97771897df3fc80dabeeb39111f2e1bc125d6a706dd75ab7c06a6f8eb5691e4c88b406c1e31c76b0ad24421f7").into(), + hex!("8373499d411faf82d65f845679965c4807c426851a881f5fadb0a580753c2889207c4be6b7f198d21a460af0af6e04a5").into(), + hex!("b50071e910a81f5b6d6d7e0921de061f82a1ba0bf97a97e29fa4d07d07777c71765ef9771ad74b2eb4007cc98c9ef9e9").into(), + hex!("a318d357afb13d0734d35df715f98e6572f93e0dc0d271bae402581593f9c0fbe931e623b9b563cfcfb9b226d96d8b5c").into(), + hex!("8187b65888a5da17c99735c4a1370865e475394426fd2d47fe20fc6046679d10f12f9524f34023f49b36c84009a55681").into(), + hex!("ae9811057db9d5c2be1ad726a75b40a664ff920f267dedcc1f71a27b9cd96ff0e0db5a6b17d638b9a716b26e9693f5e9").into(), + hex!("a996d50d0aba322da2cec279aa64eafe9af5734ee6e0c725b9cde9b0f54ba4aae97d57022f47fbdd0ef09e0bb9003b5f").into(), + hex!("a3b4cfa2c38f23bfa67bb8ad8d912a32ef97d5520ffcf8f64da415377e80df39d67ae925dbfcec48bfe941b473eb40af").into(), + hex!("9640b1c78e1267fab0c67d6a902c40473bb33955cc6498970ec62edc8dc4a9f8cb4eaf9291f618ad3360ac33ad792158").into(), + hex!("8791faf25c0086e0991d7d14533e461ecb51870f3417290f490b034514f0604cef0812692fa92c6e6683f6c52d260f46").into(), + hex!("844134b6c2662e015b7e742979c3395e05e33490cb3bdbe8490771c5148cae6302e06ab5c707a103784e2358e43acd98").into(), + hex!("a1ed8d46779b7adb0dc3727e7ecc3c4944a60e6518093135bb46dacffca21643efb20554a30c4c2fa73d53fe59faff79").into(), + hex!("b20dd15e201c445e6cf5a49a2ea2979cd2339bfe21a7eb4e996f345691e95e630a516f25db007d83ff6a96cf63194eba").into(), + hex!("b7cb015a991dbc2fedd47e0dcc66af30a86302ccbf13c9f1d5020c4fb54a86847b0ef64acfd61e84e582c3153cd94942").into(), + hex!("8cb6d763100ac289fbcf7b1d259baa6db4b00bb220ff0e97896d47ef1485e4cb01d24958eea5dae6838b38d3d74550a8").into(), + hex!("81d1c5e7a4b922583b02dd8e328cd564358ada1d1d58076262c5a1bcf7416e6b9988f081ff154c0acdb2de869fa73424").into(), + hex!("8746191d3e3ef97dccf935b16b3d306b6a5636e274a78ea7531561b3ce92f97437911a3ddcc63ebe34d875d9e05a37d9").into(), + hex!("92689db2982fa1793d8a76a690bef928b59db01df1d7c1b8568a8f8fab825aed07dab7a3ab277e86e2307ef0d3a5656e").into(), + hex!("a1f978236ec0e3ce8af63b19b6523c237a8ce435b00a17f1e5d627ef36a3c1f8e4cbea6bf2d455b9b778ca7c091371ee").into(), + hex!("867c2b702b2ceb2c10d94e86c44ec39d6faf2f92c5f8b6030f95b6558f287d47b027fe3032ed8e993f6cd6056aceb8a2").into(), + hex!("97ae230a44d3318d8c75308f6b473194f62a884369c2c636963f82a11f69cddcfa397b28a3b457d9ec81f47d7e1718ba").into(), + hex!("95712c05d56fcef6342971e71f3d3d414b4620adac8d434f83735c5d28c44ae25853683ef24f876a0d3480f4e623a655").into(), + hex!("a2a22ea77a0bdbfb6d1012ea3f5446c164895b9862ce9e347ba24c9ac054a0db2ac920975ed1254d744bd64b08761f88").into(), + hex!("81dff1b4c03d2ebb1520fb7fb8ccb0886b6d5d4620e8c9f97ab1da39e67e2b29b668a63b69ed7d97fe25db543bd489e8").into(), + hex!("94786676020044db143c3ae7218d5cd9c2019dde9e4868b3701f1fa7c28d54f82c8f50dc60d68f01712b1574ff912ae1").into(), + hex!("9318341a07e78c2562a9da9aca75241e3fc7b68380c5fe636af37b053da41aa48624d2dae24d057b5e8386d3a35abb57").into(), + hex!("a8930bb5ceff7e1ba192192b14f75a3381eee0bd6f6a2c67f43adc1ce57ed1cbb64a3574be5ef1515153ee6aac51d809").into(), + hex!("88a16ed7ec1d78568532b4d3050c45e0016d9d1b896e9b29db6cbe2d976dc9498cacb7326186567f621defb9c4ed3ad0").into(), + hex!("8473c467948aa778e3222f5cb8ecf25c53c975840b6a2eeaf25fd5d1c89a5bd90fefa3252269f830f69c2b38e767dc33").into(), + hex!("a055c95fb4c6b0827b6965e2cfadd2e37608b18ce9ac5830fa9ea3e97d603b9317bf5ce736782740276f9cb5166a2970").into(), + hex!("a62f9517ffb9b0405a8ad4b74ed900ffb18edbd5f59fb8770ec4b282e91d7d167efeb95d7617eea052ed8e0918de77e1").into(), + hex!("a7e9563d9fba807036915a564afaf7b93bed7c9d249d68f5a6c56c2cb35ed14807441a92b813a0c69f63691f549ca400").into(), + hex!("98ada2b51e8fbbf4d101fd78dde440bfe73d585a836e00c5ad33586229c919dd3d087fe4db2ff994807e91eb6254297e").into(), + hex!("a68fc63e1474fe08dc03a1d059fe6b928f48d6c9662e9401e41a5c4ee45077a1c904d62c0b0b76a588e6b38596935214").into(), + hex!("a8accf1025794d087bd36adeeee1e9977fe656065ee01edf1c3e4324c6a1e2e2dfe95e68e1684958759e90ac3d939de6").into(), + hex!("9055a0df50b948af9690e899ee4fd4a7251be2175067d20190afef112c4d1903bd78ffc380637eb3624ab0b462468b84").into(), + hex!("b5ea157f31830c779f2e7557d53b2217b686961f66eb3335b5e3db49e099094b61e9202dcb90af601c416d0be0f8059c").into(), + hex!("833ff4a7e06cc8705273ebc7436a957b4ebbae02b7f76032d1a22261d71d9d3183ba5944fe53369f46214ef8425d0f3b").into(), + hex!("8bcdb48edf6211687da8cf2e2173c1f67fb9f143e4a92c0ca2585feb2463d624c933b6a7fce9892ce6bd9c657b8c634f").into(), + hex!("8cd3e12538cf6229c54826fa6a404e9c0fb167f3f53f1e7354772b2a87544478de47d3c47a01970db2054605aaf8a75f").into(), + hex!("8d3a4b65c0f9cb4ecc53b6472169256347cdc3f5d2a50d87b8f6d1a3234f8e77ae8a9354e624fd6e15508de60cffa586").into(), + hex!("8759c327af5e9d69e478370a07112710d9e0a03ef5db9f4e4d83c2e980dec3d8d233dcf11227f46cc40792e00fa181f9").into(), + hex!("8a72c3f4e4bfeec7733b532ded35dba7769092d16967d262a7d215b30f203c18c561d29a6e205f36f4b15c7001faab50").into(), + hex!("ad0ba4caa020d4dfa4a682bc33ab5d167045eb4276ce777d90a271d9f16ffb3be2db5ea75c0469a168d122a374096375").into(), + hex!("86e4bee1e0c694102350539f4ba08498561c59784d39e1321f175e0e4315c5f4795b82a2bc0b8c7fbd840a1d4861f5b5").into(), + hex!("8aec422f9c614bdf7a14c20e2666a48f274e1ab2583826dc5a0fbd3f8afd9649fb5387bfd95f1b3aeaa8f1585a767ce8").into(), + hex!("8f553b953034dd409506191b021bae2a74ce76f6a98cea0264a9a97f79ecf6105fe17287b805eb828bb7e486779bb780").into(), + hex!("a8e9db981359b0ece6dcade231c2f6dcf915685e13550531c47dc7412416b535cab4c12fcf81c19a8606659145d3d46a").into(), + hex!("9797b7daca1821cf6b3aba05e5c78099506ec52fed5179fca7a880e0064fe1876ed83c607e50b38a11da4c57a774ba39").into(), + hex!("8bab1f3ebbb480b879760cc1b640d5b97538f069b04fc85bc7860a3433d03a744606328801d6569fb4c822c1f9d7adfa").into(), + hex!("ae1acf60946e115a10678047aae8fb40872bbc4683b9fa42e74d25bd5d9d49be6b5135dc989407c24daf8f6c12dd7649").into(), + hex!("a01836efc39ff41c9283d90bc532ccd4aed815f5a6f71b3704e9fa9eb718b67b15f45ddcb00d054c5687c60d9b66cfd4").into(), + hex!("b38f914bfc4d78dbe99c8c2bbb1bfa7f3bb92a22f7a842573660e20c0114059dc6e79d03e09f8f2fa3ab33c1b36461cc").into(), + hex!("9774a19aa64488be10560a3ecb4e36cf1c826ebdb1c8875378197157caa2b2cb048e32e3ff16074f5442feff3ce7fc45").into(), + hex!("b212de79a3cd09f855b894b190a2dbffdffebbf18d2ad04bfc26d195252aa52cda5d41b1f7a42310c72304b2b28a4f77").into(), + hex!("92621904c5ae3987f9466624b2a59503eb3565ed4e44c756109ff105c13949a77bea9c4bf58bfb67c9e5473b315f8d14").into(), + hex!("b393161e88cf46085bb85e5f4093cc00ea9f51b5813dc2d9f383c4e8f5ff8377070c7c9740247271beb58bb8813d975c").into(), + hex!("874544abac10a940faae6b06edb927bd4cac1655a50c2ef5a99c7b1017f513d1cc3def82670d5a67a11a0d5fd6eb1fc8").into(), + hex!("9630062d01374a7891ae58d7f1b096d6d5c4826f9518a53e65e7b9250bf319f84451a0d7a95af9134fd02c852e08c620").into(), + hex!("a53046d57bfe1c32453af686ae7c7e751cd2884d7a1d4de327bad9c10cf49550f32bb91511bb865b92db423ad6120fdc").into(), + hex!("96c0053f673daf98390554999ee32550e14597b2350acb9717f87cb50e6218489d694d0a07f6922b2556f026aa036fb0").into(), + hex!("94baae1e8125cff266629c493cfdd0d98fbf6fcf5efac9661bab0f25cb206240807787c718d7958413ab1c2bbff35af5").into(), + hex!("9677f6ff799d8cde162e05908d62cc708154450bac669a37c19f18fd4a3214a07bbb50d020b8251dcf7505fecdf3fa73").into(), + hex!("8641688e4052f636291d102a0915652ff70f2d372ebbcbf5266cd38918fb2da16bd3df0dee83e11c2845a10660e5ff13").into(), + hex!("9038685e59a59ead27e2989524fe0f8c7ca43b6b1d4a36f3946d3ce7a3670c15e7beb9e814f7ce65e813ee091a2f1be2").into(), + hex!("8afb4c7e592864a52c0866cab38bd640cf355e6c8db9a2a4f8ac1917b0cdfa6e9e597cb6e7fed7a0043f7f534a0743c4").into(), + hex!("8d5052fd8accef40c9cc243db4d50da074b416e743310042d941e851e6e866242561eaca905cd1d3277f735ce805ba36").into(), + hex!("b76e333a2718c65ad531a0d9a60ae8bcdcd331e5c87ad3ff0861f00b82b3cd0d987829c50394dd54580d83e2cc51ee26").into(), + hex!("b4780edd4af4c2b4ed559fb135255aa3e4261102cacfed33c835d5ff603218166a75d399f9e7fa4ea807b0c131058ce4").into(), + hex!("866e7efe22528e237dbe49b4c41f7b495617e9454f9e46d7ee154600a1a471996a4194b2a14e206fc7bf0632486698bc").into(), + hex!("954a72b4ecf47fbf2f5de7a462361e067ae83249720b6caaa8c1cf04640a966ac32fad4d91ab422ada74fa32a3ba7cd3").into(), + hex!("a9fbab2646a27947a7ba8c71051a904e85106fc2d57b56ffb6dcdc152b49a6b5be2336cb74b8d6ba3d049e7fd8acecdd").into(), + hex!("882cb77aa7c1bc68e7f21d53cb74e82454726ac183aa05c8bdc3212dcc5d3a711b9e27990cca26421ec0495caa0817e4").into(), + hex!("aa786e0a23e9d183f2a0717367848a8df113d94eb8c145ab5ea0d909ad43ab9bc18ef079446d1e5b62a45aecc66e935e").into(), + hex!("ac01f1dcc9d410cee5276c3ba20cba3d25b554b7c61e83948bdf6ef9d5e937e6dbd27954adbb8f78568fe3cd02f7f49f").into(), + hex!("b213e73306d433442378c2953a49be43d1902c6ceea796cdf2411dfb3f5f3d468c1806b0fc4763953b1057021275d8ac").into(), + hex!("aea0ca8b5627083bc33e63fd1f980989b599f35fdc61d907e0d0de391d04d05d52d1ab45b8c898f7664869122c671af4").into(), + hex!("85820e4941f753ab46cfb1ea2d8e8fcf27f2f3a5fb192ab791fa1a2c0c7747907991eb2c785dca3b3d120e4ee8f29937").into(), + hex!("97e4fff547ffb3479e7b9c0fdcc516cec5cc5678fbfeb7102cb276b19c370bf8523c47cb73bc458eecad46b478a0f9c7").into(), + hex!("a32163070d638fb8af7f001a629e51ef7300a3ce47c13a20088a6e68a1db8e2964ceb47401a9aef6b1e7cbc596ee0f6d").into(), + hex!("b59399f931378cfbb2411972f8f54c5d29298d845af31fa03e9d5809ed134c170d29cc3ff742b4c68505c929673d114a").into(), + hex!("97ef7ac6d56d092855418869ce161906a317773f333b2c2d5111a78f7c4a8aeadada1210245a97684365df776d77d4e9").into(), + hex!("8407e9ec357d4b0fb5a9dbab4a38fb7ed570d8ed328ac3f1fba87b4083ac3f403a9b63c02582012087d7d5a5691fd907").into(), + hex!("9630db00c95989636e0f50843b42748ea222fc53ca751d5dea0c46969f9b7fd84c694c46d45d712475be6c5b55f1bb7f").into(), + hex!("b18461ce751433ab392cdb10bc8b2f63c82303c8c26b5639c03f2a07dfb71e640761afb8682daeefcf5515ad2eff2b3c").into(), + hex!("99142237fc78b5a36a6ea27d28645bbfeec461a6994b81d036ab46292e22d4e061a1b72924094e3f8602f675435ee6e3").into(), + hex!("a7bd7ac636b94fc58e5b6fc1da7b27f1711d785fafd814c9ddf94f32f9f3de82406ad0454a56f331cbd33c0f8f150c2a").into(), + hex!("85dc3edebc595974378a20f6acc20b68dffa878cd61deb8f0aba7ca3fe8101256883543c5d36ecd2d4cf9289dfc52241").into(), + hex!("90b9e5ab77a8da53f493d464b0a02949e96931f634262824df4a6a6b4fd0ddf7153cf5c7758e370fc71f991691d609fe").into(), + hex!("b123cea6d44b1b0b9523461516faefb97cbf844a5b23f85f97db3e770be554e57f14bd155bf6f76567a3347925ec30a9").into(), + hex!("a6f3a0552e621c5847ea162b80949d3274dfd70a1a1da9b50800ba423d5dc3f868f5bd18fe43db41d7d960fa95233329").into(), + hex!("b6c33a14b54b6129a4fce9145c2aa945996f0a1fb0a6a724cffaf2f7ae2a9de79634f08ca90df67ff877d7bdcbb3e1d1").into(), + hex!("a3f3d3959bb5fc246b98f3a1259853874fc73ec738ac99742cc869bce96da32fa4bfe5a42dd94e0fed2e725168c5b4a3").into(), + hex!("8b293780ca14d26b7cef541ff9b520d038f1a692dfd678747b9233307a423674b21c3ba764bddd7da163c9e782aa7e05").into(), + hex!("847f919e596294d101c9ed376993ec794e1cd736df620208542ff5764214274673985c45b8eab86c2421a85762263a16").into(), + hex!("924c2965788e4f68e3890925926a1a4912cc6f9de44b6011294a28227cd370c0835231e4e70bfe9e32d1a86ebe7cac61").into(), + hex!("a26e6b9ca2582c90185394aa6fbd3cdc1e48908f65b3f996488a0d221f68351ae6196403c6079a31c91c832d078ff583").into(), + hex!("a6de52fe7fe56e8690931ae819697eb0f1baa31bff1c11f433fcc71770ed20c65d92ce8a5fba5c09142bacc4a2fd1afc").into(), + hex!("8032d04c4e75c4ffe9416e3f86daa8a25b9aed4d4d342b63f37b3a05a6ea071506c444c0a1824254adb60a20905f854e").into(), + hex!("81b176b69b8e53454d0f5a3470313ab0c7547ebea8ff371c4fbfa5ed3e65bbf911bf43080c42263f422fa12fac2c847c").into(), + hex!("a646243ac37ba838eaf1693837ff341c9b6a651cda1a98d81fa4a425949c94de4e3c72e505f04a50ac3f6b13efe2aa31").into(), + hex!("ab0147116926a8251f376887c1933cbc3f1cbe7d98cf530463b9f8e6f91c635b82aa968f5a281402e1944123963aaa6f").into(), + hex!("8b822e131155ca08725a0004f0033f0d1b8d538af3323ba8880d3f29cdcd0120cebfc5c9bfecf62b0ca15bcdf7430fb2").into(), + hex!("91a779d0cda4c7293a9a571e3d0580be5cf3a1276a249dfb2d19a97971c4373d1e43885d3b57c7b5021953a6ba9d93a4").into(), + hex!("a918518d8ae3d74c5b613b6f0758cfc4fbdb2149f9b28972fdfc15e20d6eb56f040b4ba068f1730f6c73343b2d2f2240").into(), + hex!("af9d979b3e57394cfae465952f2fd40e40aa96bebabc6d9fc2d359e616eed1c37d9dc4fe8136bcd8e4399b9213adde82").into(), + hex!("84d2a9f0613da5b3b71a482b32b1ae1c18dd173ab7bb85e604a9c180d4428d383cc2238c1fc65c05a70b470d07c7c900").into(), + hex!("958b382547e4a96f41545297244cfcfe0a2ff2a90f140312957ee891dfc6234a28e96538af7d04cab3639d1e34af4b5c").into(), + hex!("b93f016a8b3231a267898bd6fb9e99b1218358001a737a7954745c52c2d6ab330a7444e978293cef887f5c65a658abe9").into(), + hex!("8e4c93d794e8541aa9741241d2782d12ce299ca805bc8a6dcb5c5b7854a05b0ce66d7698d4567c54b5a19e876eb53edd").into(), + hex!("840b08b719f77e5d035a4d72bd44174894be4076fc8b4808b4c0c719e644694313100794e76131ba9c74702708f70b93").into(), + hex!("8fbac2c1a89fd1fe8633b77519578eec86d4162c20259ce36ac4f8fe84d6c9bb2254a62d4a0a9297421a27b096429b2d").into(), + hex!("ae9e9014a3aaec60d134bfab74fc17e1af9d77013903f29768c9852e20767d8f4181694e7792d8ec3abee4abb75ef416").into(), + hex!("995f482157a1a74b4bd353ab200cebbfd8cf95f25eee18cda4bd911278dc9d928a1b7bb928539e808fcd82807cf503ea").into(), + hex!("a2ba63bc93a536714890616178cca781888e2c8c5e51a6601da05802cbb0413d627ce19de639e3d0c3aec08a15d8e762").into(), + hex!("82bc0994dc0195a4bc8ea2e1c3d7c512d74555152f8722d04954ca3bd5103ca714cee3e05fc512fcb61322fae7016c63").into(), + hex!("8b1a1d8d867641c23c650261fceac36b0c4ac54a243b01cdacb3377ed3181086a4e9459a41e927aa0f8125f4c0b505cd").into(), + hex!("a630c12e206f0c99e5140df38ebe867839f2dadb69af47b42ef0eea20ced2214800455570aa810420b7207a0a288affb").into(), + hex!("99fba4649399bc63cba1e2c87065050cfa1e0e13b37fe56fda5b962c9ee96db162614bbe5643e52ac69370574749f0b4").into(), + hex!("8046a9818f890b00baac1bafeb8d44cec8504fcb160b16425f07fcc6e99e03644e974b8d17462686c298417651a7f931").into(), + hex!("aa50676ffd8ccb8be175e217de842ad0238d6608bb2fd15a65a675befcbff849113345a9d5ff083df9608876b5a8bbd8").into(), + hex!("aa41ea68d7777c171e6a185e9e580e8c0686f2c4ab3b29f2c2f56c27493578a7254c5936ebf72149054dc0185d80bc0c").into(), + hex!("a8a314c0218a0908ad936d10f077e0f5dbf4d3de4e8a2a7eea287471d01ba38fc7a549aa5b4163bba01f7bcebcd49c20").into(), + hex!("a1275ecf5433a70872dea93480af81edec088087c9b69d59f65210376cc666ef5e746735081c5cf249316de6229afc5b").into(), + hex!("88bdd7f6627c771f8956d20706a142b79ec8f1db8fbd5430890df0a24835cfb0737891d2c53793d1bd959cf8d97a0984").into(), + hex!("85bed4d7922103f1b9aaeb7a8db8d00079b12aa026b9ba9257ed59c558d57d7b948355559e10af2f9a030eb68a4ee7ec").into(), + hex!("9798b45294c94e5572fa92b932757b8c7a5d1d74b8a5706728fcb5a433fcf088b76606c7d6592f561c959be03ae30fbd").into(), + hex!("ab30d2571d1fefccc95f57af9b2775c66402043ac51f5a6d0aa594b1120a69914b0f10a9a12fd209ab45b677443a9360").into(), + hex!("a4ca8920fc6781b9bb7b36a66cd88f0cd328d7c0ae3956bd8488d2f3513c24eedece3bb98fe2a7318dfb09dffff68b90").into(), + hex!("b4f96a47ba0b2f7e040c6c3d1773d588e086a028de9f1b353b57b46ae1e7df7bf614cf8fad461d30c446d591790e6b66").into(), + hex!("80350ab139ef69a021d18343e1f753311eb646dd8a9b5ca7526311ae3c1535c1b5e633e3af5eb6b6b273a11e6aed2266").into(), + hex!("91a11ea8f7733ca3f5f03225f7b8cdd9485785554ae4dcc7ef2f38a00c819a798c50b2a286c431ea955ce39cbdfcf651").into(), + hex!("ac5b8b64e633aea87f863fdd4459d3b2bbdc0fe198d4fc23bdb19a0bbe29dad719e1e1db39c96bd52654657149e9be06").into(), + hex!("ad86f8229a0ef7f3e487d150ddaf9bfb9e044eab566a02f9029619bd1560e04c0b0881102e69c215aaf4dece3b86141d").into(), + hex!("b6b3566476108d5da3cab60bfed5418f0f27b0c19df07fb5dcca4718adab4ab79f0d2991151ed81046b1ae2bb2eb4b88").into(), + hex!("82f77771c7ec113d9e49c25561a259c94d8f2c59d4a3a12982290f4daf0d553b50d161ad0c2da79f88198cad3865abca").into(), + hex!("89489e1bca1a32a5c067c9776c7ae22c1582a7358a82b43409f6cc27225f6dd25a8244ab428b93c1cc9059fa40fa2cdc").into(), + hex!("b0b83bb74a0845bd81ff671327c0a7157c093aced14e58aa1b3b1b8e2f11fe331578d3f0ef209f829254302b5ed3193b").into(), + hex!("93c7ebe10bcba37ad077aee310a9277bf95e43b95327d00dd4729de05c1148a137e4e4f9cff451047a96c41223a06536").into(), + hex!("b51e1b00db5c45e04f99a0964059316c2c271486c9eacc77b48846a582edce1a39e5016e25ada14133020efc60fe9d0b").into(), + hex!("98b7b90c02549ee64c55a8954355160cb462ff2d10cee24877b48d44a1a6d2828ed4052b42c1ea57716e2eb1ccf62b39").into(), + hex!("a82a6417e78e6af7aed62a633579cedc1d0e9fe8efaa5058b3c6383c5ff0d6ba0b871d7eb87a5634afe1c585a29b64fd").into(), + hex!("a145410b40abd0023fbb9ce82b59787966e7376fce7e1abecfd4cc9525966c49849d9e516b6f762d0a30fe4cb33530d7").into(), + hex!("b4e466bf64775e6a48cf19f562a7876559d7978d244d45c301d5697b35cb7228b433eace510b763f075da80a98271dc8").into(), + hex!("80bea6b7e4e26dc9b4bd1c4b38745e77ed1923560744a54318678d28ab6b47e776be5c31fdf058e8b19f44948cc86766").into(), + hex!("85ef84b1987f1c050a4f8cb8065356d19a484db55cd67498a2b4ca2f72f9a710486bb0d63138654208069029d2777c74").into(), + hex!("af0556fd011d570857d05d93df33864b1dddd10fcd314fa622031d5b0222cacc412a635d53dca5393f13615dbfe16def").into(), + hex!("a7a6ec4c5c687ee1bdde615775086be65d6bb3dbe19c0df80f045a6640bcb0ffb931be1ff0d1205b4ceabd56705b8215").into(), + hex!("aff42d6f5f043109d92412e99c9b2a5163bc410bb63787125ebcc230f2f80a6d665a3fa6301f002ef48158fa855a8fa8").into(), + hex!("b6cfcd44cce581e92a09ab32f3abb07abcc1e5b07bb65fe55f4bc0ceee00d9dc9107736b3fb3951b95d20fa057fd13f3").into(), + hex!("815ba88a2a39a00c0560b7620c0d510577ffdc8e41323dfe5f8f00d71132c092c23526b0ae6ff6681e1d6ab6c3e46623").into(), + hex!("87e112afdca3621452b47ee31d91e6b76f8f714f850f83b0901c1238b08a9fda384caeb2ab64b57ee7122941fcda2d25").into(), + hex!("b4d5709f04600c13b5640f5c6a337655e224600a76b84d3a1f09e92d383c71901813c8095aad0c7a272c9b6719607e0f").into(), + hex!("aa0269238ab2bad3085b1a51c9b461d08a3f9103c53a1fbc3ffc5cc1a657e00476a3e90a1b4a11bdc00444c36bcd0410").into(), + hex!("a9850c0f254301b519a82b4eabb66b3fbfc0a4dd4edd98232aaae8056fedcdffa4ec11b17f0e8de553ed577d69501bfa").into(), + hex!("8bae915ea56b31b1524c4f500dd9eb445b2cfdd482ce8ad12b5736d8ebf8adf124736b868c1c7680c7e9f2b920f09e4a").into(), + hex!("b8cbc0986998d7a2089bd28c0900b4e8b68ade0e7a8fdf9ccf4e244639e141126a2f835a25dfa7980944e509ef3237d4").into(), + hex!("ada12153b600de955318df5a8fc46a51b3fbd7dd681d8330e9830f47f97fb7a9d93ed6ea80e89a7200e4735aeb73a134").into(), + hex!("a1855e95b77e48fbcc2ced2ac9eee236f2b17d204c1e4f3047951307e71ba38af975a9908a025fe5d844dd05836ab24c").into(), + hex!("a606922d4aed12ba3ba4b1ed0489acbe1b3fd3b7b798645f6dc376fe5083d586f889e8fea0470a5b8a4514d7b9b1e62a").into(), + hex!("934df842bc666333fbf12901adfa011b51451ae3b6c04d12a437801d3924e3cc74188cb809fb26e7087b15063c1bce89").into(), + hex!("a759575018e8b94a1f4d2998f951a74f0899e44288e7687ee6518c38c4241b52b94992b95954ab12f4424776a328ee67").into(), + hex!("8804cd0c52b7f7d04c17d109cb3168c5939fa6386bbd178a8ac3e67d43420d8d57779e6a0a982e42cd9ee7763c9afb2e").into(), + hex!("aa8c632a8600128c3380fd46a620be79bdeac56fae0ff877b68aca28374a4b6552c8e98d83a847471a92f74bc9cb6ae2").into(), + hex!("b400363f85dd8a99632ab07ff19ee097885079d507b2943c9d69037de12f1a65b0f74ed87939feaf5c9805db4e6eb808").into(), + hex!("aed74634ed8a1fa181db46e202f1f646e3d6586fe9695822b424dfb0211332338e45c5326ed0c5242ea31bcd4cd435a4").into(), + hex!("a8f3b14886ba06c8ce95c8229480dc87112e0abecb1a8047f90359109e77daf83aca99a56f8e195c2bdc22e3c991b648").into(), + hex!("8446741435af2b4cc6dc30e74c3c27d1cafec49dbbf8b7b41beca2304df84d9518475f24f1a746817fcdd0c3c0875e75").into(), + hex!("91ba3151960a4ada7234aae00c0f171a81549d1e07beda21db5a6f6671c1b1bd3587543c833146f3c52a0fac62ba81db").into(), + hex!("8555c28aeddffdec6a065943d2ecc9de906bf8715a27ef6e3222e89bd55295c61b59da4682c249d2ef70fd20b8115646").into(), + hex!("b9b86e101cc1769287cd6e25b6048c64ceecaf7f56bf4d8b18b15992d8435f288ecd84e872399c5744e3266a9563cff2").into(), + hex!("b28e43e5404fe92b59b9b2dc45ab4cffb4ec143158c9f552f850801083fb9c519a26d1455793359e173962b82a204704").into(), + hex!("af792b54b728bcee179392c9c7c9bc1ef51790141294ca34091da99a5525635fa9fa700bf9a06eba7e1e6dc9433975d9").into(), + hex!("b9bf63ef347a5ed6c083a2b3c9b99ab4e6075e53289f55277215b0687f94636d42e4c937c6a060893950c4bb71033a8c").into(), + hex!("b6eb9484e48cf825a4bd39f5492ba4ba3089784528c6f9ba91d372bdd3eaa77790188fa46f8cbc69cb346e83bf6f898f").into(), + hex!("b678af94bf007988731ccf872808ecc800f64c59ca257923d60116e473629ecd135a8b8b785095e4020600180dd61639").into(), + hex!("92f1b51a2ccf1a8ea328053b07c45b30c4204cb7661cce7a19a23e6abe59c406e9c8e1a39e9d9fd017c0e147ff0caad6").into(), + hex!("9629c3ddc41c5c64af2edbb2253a267991451f83873508adb3e2eb0c8ced6c97bac1ac1903ff0c171249122d34d0af7d").into(), + hex!("8d459177e53dabeba6b02ca2100151cdc30aa1aacbf9a9b5ca1707f5a91a8eb63cd775db119a20b14a2d09c2f0f27812").into(), + hex!("8a5f256046ac918cb9e772d60e6942a76dc6c8168da7208c5644d9d20f7136e4beb089457897d23f8764ef5c6f7cd152").into(), + hex!("97ad6568b0d984987dd27303176e048d1c2c261e9546c19d9b640c85569e4bf608cd321bc21cbd07a86fa5f34296ef9b").into(), + hex!("abf45a52003525ead4797b91ac26efd98f2a8ea95ec3f7fc363d3995ebb9b81a5c45ddc85bf13233af97c27a4a65f416").into(), + hex!("85c87940a98288bb57515497aef45918b8936fc011b6e4c5388b2790eb54c23eaeffc9b2ffbe8e45607f12f87087a4a4").into(), + hex!("b14841eadb8b39c281ebe06979325b3b3fe1b5abc0614b13d3d2eb309a66576c9711aa2051b720e55fb89d59bd20fcbd").into(), + hex!("a1f34467f2a66f70aa293a56562e2ca0d50067b31f8dfb6dc3133150ea0511b5b3851d94bc6029d55eaefbc221ab41bf").into(), + hex!("aae949bd5253c6cd368e7551889dde335f330163809c5ee133d7f7d0786f5ff5cca9eb0ea5516febedd6a0d85875249f").into(), + hex!("8b07def191e57deb39c4453b2ab4b380cc58ecf6541ec0e47664ab0341dc2ac53d8416fa1409886f289aa4e28f26b190").into(), + hex!("a2b7076435ba5534a7101cb0512177afa3f91df9be43334f9bf22b41553c817ded26a06d8e64b37e332c77674cf710ca").into(), + hex!("a8af4db9c46735a256b146c74c80aba945bd64dde94b6a63aa10915179aa1f5ce5a499264aebc2587d9f4aaa0c1f19f7").into(), + hex!("b87e88f17412d8a7e8c13c30ddfe06e3dba913104edbe7ef6970e53111390133678e964c15ebfd2aeecc84f50185f7e3").into(), + hex!("aab006f927006db1837ec7ff1aa1763e3c40b164d2bcb530e158abafe3a84f0e8df77d3f4c2f7ff60312b0fc4dcfd6fb").into(), + hex!("a665363274dfe3f01212c232628bdba79dd8dd0b96604e1a8ebac1c055c6492d92a2de3108336646171a32e0275fc9f0").into(), + hex!("a81f2ae4a0343549b0127020404de368a18e4c65ced68e8fab7d1d9a5200c9f598417eda1f495b6f7e546bd64c6c50d2").into(), + hex!("88a5892f406e84f74232fb9a524dd5e68ddb776af1c782469816213c0d524bd9b52fcd3c11addf7e9ea40c947e1b842d").into(), + hex!("815705fb3ed9eec58837a8cd239ce39879bbfcd2747cc0640a3a1ba2be141826be5d41c19cb2678addafa200ffe3f1fa").into(), + hex!("ad8d05d484ebd47d2f39a20256ae9ae088447c1d3a5c4849a6495c22e3d76f888d5a05242fa1b6a0c7b3f81d464df6de").into(), + hex!("96dc4e4000020e58a76e52165c1a0b9b6a3cbea3bff3b3cdb4c745437f252474b4eada5abc42f880edd3759667a60901").into(), + hex!("98e0c5a4d8222ca94f4e6ecff3beafbac459807cfd011ee988f9fa10d868863944470613ac0b499c249b84e1f7824e60").into(), + hex!("b53a979a9ed42f8cab949a23bdab63494e2ff84f45da49526762100e1d5a0fd116eb1c285e54299555e7f7e782ff3c44").into(), + hex!("afd8ff8a25ff8aa9c038098c0a1909ae3b72d304626b57d43bbe8e3e3d8e92a53101d23dbf831e4b93e4d58f5eeb67b1").into(), + hex!("a9d04d7f023583f7561f8b22b701f5e31dbe12bd40dda1b041a4757a726f335af20cba57ae680ba2154a0ca6ea7dd111").into(), + hex!("afe8e5757412a29772515219ababae549148d270fa608f86f82a33607646475dda25dcee11cb0e2f32232f4c81b5500d").into(), + hex!("883c127751f399b79f3670020a6c7f808305871e8de18e44d3c799a65430a6b781b90f4bdfb294f2b68bdce3cd292656").into(), + hex!("90745f9d6be5a28361a48eb45553a2fe346e725fb08a0e393db48893ec68b47c8724aeaa75dd3dfe439eae68c2c42e47").into(), + hex!("959a5ccbf40a0b10c4fc8e149305542903e0d9656e7b6b75266ddb54880b15beab7a3eb1fd87383709f392b34bb257c7").into(), + hex!("a7e2192ba707a910e4c90814699deb56ef545bb1bce5e5e0028998cac02fc67b064d06a4dd5559ec89dca3e5aaa155ac").into(), + hex!("881e6967a4851f61a008357ef99a64492b9469b76652d1564c346afa044e571522bc9f995ee34eaa4e5364d83852a38b").into(), + hex!("b91e1317b64f3027cf56d0e6b903e9ee49487dda0a3609b16a7fe3a29ec03f2ac1baaf67dfed9f17dfa47bf60a05e7bc").into(), + hex!("80b3d965870071eebd922ce1eec777da1ca8098d4f83daf5d11f03be4bcdc8c59c68100e5f9c35768c18e1aafee063b0").into(), + hex!("90c5aecd8ae67e208708ea41b4ccf1a4b05b969d77a4ec61999a1e045b2cbf5000183319dc83b914798bb108dfd2cdd8").into(), + hex!("8743bf5b781afbf716256f2addc121529bcd350ba0b611fef6cd1f92dd588f46a8183f6714c1d9fd399f53afdc9c32f7").into(), + hex!("9421c4f18f8bc2fdf91cfb11449ae0bf385c06984f1b499cd80d94b189bb36a967879b243ffb50ba1282e2eb34f0be64").into(), + hex!("8a8a3445fbc5d6b29ffbfd5dbe98768f4141755a2c1549ed009296b8f499ed8890058d07f090e39b1ceae61f364c64a9").into(), + hex!("b869ccdb3a68789cd3fdf7af90baa8cfac90fa35eb21142d59030edf9828d52cadfa20347699e292680826aad082b841").into(), + hex!("b91fd47d2d101dc5de1eb990b00c791cc7203cea68791b12c8839018112e0de87a8cd97a99712ca56c57ca9859aed553").into(), + hex!("aab5e216b38776692600c1fc571232fac783a60f84113974d715fcf12dc4c6bc06c05d96481ef00681b697dc9ef50f6f").into(), + hex!("a59f3a67bde19a55281225ba59661519338065d5e0c44fe588d110ce5033f8d32ed3f8397a20a6765078797038d632a3").into(), + hex!("ac85b37849913fba9f92407209562107bd2e873edff1bef0141bc77f99aadf8a5442b889d77f376c17678fc1b5505cc1").into(), + hex!("99a1e78cadc41d96cb84978682fe6e6744c18678a89d35519a7e875d19761e0a1041157d5ded2cf99d0ff30e29f32dfb").into(), + hex!("873d43094961a9bd89823de52df5395d79bc88791c796a6c3d89108b1635532948b5e9500b494650d7afe2de28e7bb2b").into(), + hex!("b1bdffba9f7430229fde250bf13974e6d7e65dd315fad4928d04c098476f5324cc63a000eb19355004e896ca7b503f35").into(), + hex!("8e5d182cfd4cbb28310fc75ec77c96bb6cf7535f30fb747530955c413801df9b9dc596dc805278ab9b6c031a1c8c92cb").into(), + hex!("ae6529b20501c8e61773ee7d90adc826ba1472e1422f04086e01a91aa8fdb4fe45d3ad35c3abffe2eb0b6321ee0be493").into(), + hex!("89b294e76d91c2d904215e704c19e81405627531dcc3df360751f923bf5c132533803587bb1050aff56b20b116699992").into(), + hex!("a7fbc4dfa7c8f7c408ca6b2d74822aa1e6cf1477b070e8ba6a04260f31a8520bd1de5e543728cc6a7c5e11901b89b62e").into(), + hex!("9360f9a5f53f6f5fde8d1710340b72eb82260ff1d84fa26870b51c3db2ac36dc7a15dbcfe07e4417e81a2f5908957d0a").into(), + hex!("ac530d68f0e713e2278fc3553cce9275a6251796171af16802ec4cf8691837ebc4e5542a3e830b66e39c895500d9e163").into(), + hex!("8a748e238c8f549778f1d4af722c5db3d783310f73e8225b26a463b5f65efa1edd367754c75e3e515dc533800a6b3eb5").into(), + hex!("a75cec561d7823397c631b79a690678924ee2008e03c6b3261902be9eb5ebd3fc3ed38af88ba66b03cf53aab2a35ab64").into(), + hex!("adbc4a4e9e1ed119a7c9a8ed77faac0b248a0527b4800efc393e3c1839bd2b83fa8e9ce756bf7fed4ca4f382df7e123f").into(), + hex!("8aa769ff257bfff34f3ee44cc73d0e2048eae356d5b1b2f81962643dfeabd49400d539fa09bd8493b8f14bb56484fe18").into(), + hex!("a951b1b300be4fd7fc94a82478895dd62ff4d25776ec20156e4804664d96ae367e0e3640d05a4820a7cba0ac862b0fdb").into(), + hex!("82e23d6d57dd12ca5e7feef8f867ee433b0245f266e99fd87f4849c26d67e3c0765e130067af01a84b9962e69580aa2a").into(), + hex!("93655168f1c2282be072e2b2d09bf82cdd8e451b0687a79186ac382518e71683a13a1a19f14a7b17f18adcc2c0188226").into(), + hex!("abc552a7731a439d070671071a485e5986423a9c321bc9e0cac05fce7465147df2a830ca43f565900ad672a4c551ce1e").into(), + hex!("9888cf3bd7a63176bed1426a29b69b91bb464c495ece8c50c3ab37708326bb010958f902cc9168477909e899446f2c2a").into(), + hex!("b21040a8f6b93d6d66b8e2032ca26555d32ac3aa0354676efd390048451c1f93abc59133dd726551091d4a761be2fa89").into(), + hex!("992e2e4c957b0333b4ac788a049e729b02e0a0d0dcc895b4025ac2684a906b0a47124ab35f789cabd6e8508a793dcd39").into(), + hex!("96ea908f38a50759a230d4432f76ecc558af18fe3b3455cab0bad5d945b4fa79f3a780037c2d7cba4c386de6a459d6cf").into(), + hex!("95ae803924cf0320713da6372bcec24d3bd98945f8ec44a33897f7218ff89654babfe05e5b54dfb009831be6eb342742").into(), + hex!("8081237e2606b28f7b8337a7326f3309600da35f4acee9917067a9f8b3ebd1ddd8fdb784f17ff3212735ab1391d32aa5").into(), + hex!("96e12c3dcce48dc685d62b137137b9d2c403cf7de2b751e20845ea3c943a4601155d0ccc8e73e5a1c8a3cfe80e221dca").into(), + hex!("a682fac6e393e6cbd0e5b8942937a70411a81addca66cf0332f315d9b43481e8602e1f06706f2b284f3c827dfade8b1a").into(), + hex!("94ce226281afd7f34905faf6d614b168bae84dff1005aa5b7c3323a84aa521186463fdf5d3933bc13952f9f21244c7c9").into(), + hex!("9460cd76ac204e5bacdfd91fea5e9b2583919bc973fb4664f906e2a7df75463c27807c060a7244e3df3ffbc0a212a942").into(), + hex!("a76d328bc1e06c44d8a2eb749ac2406b304bf1fb445c3ca97a57f7d826665897d9d428bb3b78139d5c25e70404749958").into(), + hex!("82f05583db051bd97fe7947c7fe512f9ddd5273159b3b89d5024d092fef6b0b40f8be0ac1a9003be97d62c150b417b94").into(), + hex!("97500a02d6e4c616d900b981670ca2c98f07f4a10b58026b53631163ca91f13244e4edf1922e385f8bc7d822cdfbeba2").into(), + hex!("b267feb51e42c7e8d42c16c3c6ea6ad434061f359dfb94540eb63b0239d094e1f824cb845ffcafa742ffcf0fcead01e4").into(), + hex!("a10d1b551df89406d8056d36697022f9983fc1308b1ff984c2f26f734fca1e0780ecb27d83e7be2c74117c756d0d5e39").into(), + hex!("96480b4d1d61bd77cf02f8e7db51f4adb348006c368c8fe1c08a9fd34847de0056b9057a7ee5b2da64cdd5c86e419927").into(), + hex!("b573dfb42e1a3d7b4e854c4900798ba8e10b279cb6af8f2fc2c050994e4a2bf96e558b9b11ac2b43c0c5ec8d32be6332").into(), + hex!("8ba874d8efa7c3be9f7d730e1e288fa50dafb048287b3819a4a5a36962960dce88e667facbf8e6e3b083da79c63e819b").into(), + hex!("84711948436fa44cd0f93ac679e5e00010acda1a6ff5043bb3fdebe642d07ae697b20f462398429aa0572d553348aa20").into(), + hex!("808be3919570e24a44c4753deeadd3be6aebc90e4b2c9a24434daebd0492ac0f4f6e7d88e45e0ab8633d25831ecc5a21").into(), + hex!("989d217d973a1e67c38aae59629c225bf28ce2de5d6a4815973c17c350b9a67ff06b181644b11e576495fcc505196ca2").into(), + hex!("8aa8f24dd52b0a34f11000dcce719e001e746329b1b6adc217515f5a02f254a9a3c4574b544ae94a97792c8be60cf477").into(), + hex!("844a43318ffde7e63de52d3ad7540eafea87ae5e937f7851132846800e6c58c6b82851832efd6b27749e013d7d4a7035").into(), + hex!("8cb5bfbc261896110c855688bd05bee0f2267201cff868d86b179c71a4df12620b1d08d17fcf0127c394c116e5723879").into(), + hex!("856b504c50b5708e22bdd024a28addd29072b3320873793eebace0b1c8d4044c1f69a1d7060af5cc8e0bd53761f5fb5f").into(), + hex!("98f36e1238b0e2db8143373addac00743f69674717f13616ef3b4237bb4e5e6db8d261f743ca6effca26eaa842b04e5b").into(), + hex!("97574d14055d9d8003164b738888ef1c7fd3e1f0562a74b880765c3af08922c48019decd314483e703079b090e90762b").into(), + hex!("81b7e20f839fd9e2fb924df3fe247751aee84829f7198e7ecec067db9259fa50d8f2c7b21b338074b52086da9a1f7548").into(), + hex!("aeae89c0ad0cb13a2b96da3584cd4dbe0451b7317813dff53d19efa81fe5df0fc0d8c055cb69ce1757c4db9462815d6b").into(), + hex!("b115f830cdb5534ab4ce13f532d9d9eb36d35d579852350c7c3b36f03681895093d1087e6a0073c54094b98310147f35").into(), + hex!("8416cd91fe22f516890520a8ea679fb4ea99138470d8192dc8dfe11583ffe92a85989ad1af524a6af5b59e99554a6888").into(), + hex!("a30b79e8eeb19ad44f831b656f6dca394d04b4db1b1bed512e67518aa60c978fa670f6343b3dd6576a325f41e8c703aa").into(), + hex!("ac24a6b49928e5894d2121765c5e7fa608412f4c4224162a64b12b59d150a258156a3516f07a23893de30753a8be6d32").into(), + hex!("9763cd604e68a4458272aed981558cf5f575350abc6408844d1ccb5e0319e82de38207b9a154fb7cead5b49266575621").into(), + hex!("8322ff26ce9c45b530627fc364c7eef90ec528d087410d517a38617c9851d733f3486bef401958cf1ff3153d3819a0e0").into(), + hex!("86a52637db26fece46f7c857b2b8591534e2255842aec13f4a854bd584281bc0e5602e003276d796452a1204f3659748").into(), + hex!("8894d7eab796b751074ae7951697ea5037ada636b12290b5058a17a4a5f1985bf707834e5b79bc2a4cbd6bb4492d4feb").into(), + hex!("a5aa463e04d74e42e06d68104c38e5c769d2d1f0a244d65ec4c8e3d6a4bd4c60472a3d3131486c2e28211046d994aed8").into(), + hex!("a5d7588997828aa6e4b8c236cb508d9526b7bc45a26b9dc5fe069dab2317465e9461d02b3eff31db9381c8423f670413").into(), + hex!("b26f644687717513ced89878821bb109b296bd7311895e5984e7e00a5d4734ab7f311a4342e52121b916ba1ec9120d1f").into(), + hex!("a1a29e0571a42a379966035002f61276355477da5edbcc8af2b089aac891dd53b5ac2aabc989f02a574a835886080fd0").into(), + hex!("aa081322a0a9f0a82e514af43c508882e71dc06af766f8272b280dcaf7a375483af25477cc28dff8850fbba8082b96dd").into(), + hex!("af305b502236a6f0871f425fbc111ab0d57d2a1764380c9445f10e20c2bf26d5ee26be608d808f0439207610d6b0e3c9").into(), + hex!("972f23ec9c1663cdefc2843ddb3ea94610591d43214f32d12d1476d9a53b4e9cdb78c1b74f432f55c570b110d4e424cd").into(), + hex!("8fa7784878accaa9a723cedbaec88e1655901e5a767bd5d2fed97302e325404c38c0f996fb8be21716dd26ad31099138").into(), + hex!("ac3f8d7ebb4a4724eceff09c69ffaacc3ce0d30c1ca74e8bbfb7055cc8816cbbf26a0ec3ef5b83264d113b0c95b1bf2b").into(), + hex!("977072b253c4ff396731001dd6f84524bee6d22c8b0f51ba23b743845f6829d6fcb4b2e0f28bab5d98ee7a5aa64e60cc").into(), + hex!("b5873dc066716992179574e7041ebaa8896933078550f8f28da4c0993c002630890f4eaa01e49109bb8ff7dc5bd76495").into(), + hex!("b01d6007e4b5f3e04262a7f1b68b128727e045547595068133bf83b103234f73999261f858343987a333920e338c6e0f").into(), + hex!("b4c334609335c0c6202619ac70dede8dbe48407aa32773c031185917699517261c64f440c287da776728e4ccba522438").into(), + hex!("810a43d72ed43ed0da32797513e96ad83cd8dbc27c173179c46d05f493912da9fd60886ff4cf90983c9623ec9d395fce").into(), + hex!("8eb694f964ab8f7a5b668669010c212d13ebf60973fc83590ed75ea635e92298125ce1ebc1a540837f4a526d2510cccd").into(), + hex!("9530a1eb4c7f06735a800f2617671d99945eecd73093f7d3d1a5279eb2fe8764a10d72c97064b9e95dab22d88f329e20").into(), + hex!("a960ce57ec10b5a10db72bf1b344434ffd11c0a073ec28c14a58339049a855c8354d42ae9be2cc7a6a1d052046df4f48").into(), + hex!("80c7ea8581160ba06fba72813607cddf7fef9e66091590be8a924df82acdc128aafd8876023527cdc4a6cfa5f82d60c8").into(), + hex!("afbfd9b3b636db945519aaca512a53696e7318c86c53f1725223ae8c4c0ce2e5e7431a14af24286740b983da455b436b").into(), + hex!("a639260baa2ccdb6091de1c1ee4dca94fd9d905e7a990349f54450b2f8de7a1961566ce64775bbc9279d79e369fe58a2").into(), + hex!("88e184fd80ad8b221ced837e4b877aeb4e895d315b8659e03eeb1bb0acd31692942475464e99e65c17a6cbef8e8151d3").into(), + hex!("8dfbb8d52b5024af356bb1e4f5c5136c4ac9ffbb41b5922cf1437a5599251e8e8c64de9a7baaae7aea29f5547b62857c").into(), + hex!("948bedcc51ca9395dd3db8727d94156c4c1b0f6e03621a17a559162bed2352e2652509e94f9c4e9205707ff7b48339c2").into(), + hex!("a47cfd7a838adab65136c844f3320dd5dbab30d56ccd8734fd8bcb3cc09d0bffc76f066ea8c00a5210897d07a1a08a5e").into(), + hex!("91b9213dec86b9cd9e1dddf86bf371d56c9ef3cf592fce34ad790a6a453fc5fef947be8a52be99e4bbcff27be77466c7").into(), + hex!("af2565f90d414931801dab9e35ce49ada22cca29754aeddf04710fd97d78a522b9a0c387c493bb5e99413b993d594518").into(), + hex!("83673aea730dfea621bc06f9f822bd687534cf7e0112b0d6075f2e94583fc20214b360f3716555aed5fed64c258974f2").into(), + hex!("8602b08f0e643023491ec064ef309f85c3712f9d029362a7410ad4860fcf7af530dd3eb74f4fa97902b203938f59db1c").into(), + hex!("a7f2983314a2364cabcc27d1ea78952e178163ea37d3b24b0eec0d7d3aa8d71cb003c9a2cfaba3b911ef7a1cd24f4dd2").into(), + hex!("830bb0fe152bb173d31713e9177830b5f36081264ce9d7230cc52dddfa81e01c46026f54dadb2b8891e7152881371465").into(), + hex!("95f5045412f4d89c97794eaa956edc9702a86d07959cb5683120095cf396c670d19306ffd829e424b309fbd048b3496e").into(), + hex!("99ab6ea07d2ecaae3c657cfe68b841a35bae7193ef716e49592918beb1515e154d903dcfa1ecee3304662ec3650e41f0").into(), + hex!("819cc3fdb714f327cee4f5198a3b0de56ba85498b5f3756ef3c91f433d856d0cb3649ecbafb8d09094836ade3168d88c").into(), + hex!("99d2c5b9b8f3a182dafff0378bcaa1ac5719f9df8b48d3d91dc8cddcd3b79627303d901d65a35814551ee7a1f91d822f").into(), + hex!("aad58da166d1762210b7323f4333c9598975808614d537109bff5c8178546190daafd29374ac1f43a0995bfc850436a2").into(), + hex!("b66955354e2e200c2111fdf0282e5b502c221119e52fe4abafa98d29e4064023ba6de28f24e98cce3cf39f07bbe8f154").into(), + hex!("aa9d4ab2900bab98de1f70175f067674d9d9ca243a3f5edb498c3d9bf83dfb3e031b32ad4a3b4f8b17079ef083f4a2b2").into(), + hex!("b60711622a689f3077edb91f14aca7145ae092a7f6fd7f9219fbb40b0cf9113d902d83f47a2934ca43ae0f5889460ea6").into(), + hex!("88c5bbd8c896204041b5ad5fb32933a949d0ea8a97e6062c21093fbe86ec094f28e26652debf06dcc1473f91ccc9e2bc").into(), + hex!("a2f79974ceee8c3e7c97dd8e472e319373328448c84bc2c202a34950aa0984a05fd62af4954c8b87e5446ba16727385f").into(), + hex!("b808be5db3c30a0b2ed1a4bdb456c5ed4497b4e39d644f425fa22a9933397214e81e1b53ab658fd07e9c5e3cf7ed422d").into(), + hex!("89102baad133e359bff9906a0ecc2284b290cd1d9af04fb8c5fb0bade6c4a93786ad7070f25ca98594ed5208319e3176").into(), + hex!("b582677e42e27b006373d13cdb92fd98e1bfd7837db3b235b5c13fa5e403b5c56971c54f71a18877648d088ea1d76f60").into(), + hex!("aafba2363b91455b94ef58e22f17080d9f68a4d408196d1d2a16e1e83d8ceedb794c6801c978252ef7a6da40ed6148c3").into(), + hex!("83113d8bdf56d2329cd4e4fd86fed3542e3c7a3c063ef4d0c7942e9eacebc4445c7056809bad406345539365efee2204").into(), + hex!("a0b47fd7d719e756e0e448516dbed0c0464717e6906e40a616fe9da94853612b6f4f043079b258a8416f048efe02da2e").into(), + hex!("b3c5fd472c4905474ea11603b53352d98d60e388474ac2b03ae05ae7e11634dbeed00c392059c1059e8709c6acc41b7a").into(), + hex!("827809c29268505f8e65f1c271255cfa205436415acfbdee4a7ac296de9d63d900b10ab3930e1d215780c9f8faf60dd0").into(), + hex!("8050c64537fc1e2536859be5e4d80a5a5caa079ffeff6033202064f82fb4368c70830737525ba2b45473f87e194bb2b3").into(), + hex!("a9ebbbdfdb64710eb5643ba91a296fb3a518aad43c520a6fdaccac93786ac0e74be1da9eddbba341beb868e47e97a26f").into(), + hex!("816d9f9b48b76c063ec51e030dd7594dca3b951aa7ea6076374d43f26d4a8383d4d2eba5eaa44cf1ecbc997e3851b010").into(), + hex!("b0cc7724e322a130179f6514e513ca4bc71cc847f903155a1b038c661dd2771e9c607bfa1971d9db2776c239b9b9017b").into(), + hex!("a5a59b1b9fc2c52b540ecd4c7013909cb52cc2445357dd2f1b188548fb33e0435194ed5c98c841b1bdc78e173a8c1e23").into(), + hex!("8f76b23b740b7ff1ec2840a9d415b824f7c0ce875118bc648e60ca58efe3738e05ce4e401759e5af44b5ef324d26f137").into(), + hex!("b13e397f736a83630fecc35fb0928e81dd6e2afe38235bb983a3a5e22ec7cc224e6b41a97cb315764dd7e515a7a5659d").into(), + hex!("8fa3cc3b089738506f51248af603ec8493ce24861cb6bc0da24d2e31814f6fa0a288178db26960ff9bf679af7314d558").into(), + hex!("ab5b5892761b2a51b5a32b737594ea01f103cc5ccb15ee423d4429a2e7ead870dfe82d8d4f01b2e9af3aea2700d94b79").into(), + hex!("b8b89eea92e74b7e05bdeae7cce83afe77e9f0774db2396960b4d447ae18af05b0e5226ec7a0d0bc5c332dbe146b8224").into(), + hex!("831300c06f4c177bc2217ff29f02599b89a4d4b491be1057f48f9f37c1b497ab471aaf004efa6c68c1f0cda832ed232c").into(), + hex!("869eb1a11252095fbcebb44bbd66bafce733cdd5c73a19f7f770859e776542c207c1168ead56beca8774b81c3bb4a423").into(), + hex!("88aed32d3b373e98253aeeb1a4e7ac275f45a35edd54aceef07187cd2226b72e20518e783b6fcaaaf5c927da2784ecd6").into(), + hex!("8c5ae22e0620d1bb8c7e61dac818cf7c3a2b883aa55a972e4386469af2c1ff9c7b2738d8ec3bcf39377de49622118b05").into(), + hex!("8bbc2945e007c5e74d37b14548b00abbcb13c877a15c53b41553145069dfe713d6ae8489768eba1f44043488a4033122").into(), + hex!("8e3eff0641a410d817002088daf5ddc01fd12774158c035d35816448ca8b937e6664d31cf130cf3076759859ca80765c").into(), + hex!("850521b159d0a5583fdbf7aec6b5aad712cf62aff79c69d1ac357d261c52c85118d986de750aced9ee7005b357301416").into(), + hex!("b6fc28b71a3422e8ea54e1591452fcc537024caeb0bbd31b685df2d29b9cfbcecd7ad0ff3365a20e288d197e108bda7f").into(), + hex!("98b4efd60a5197e799c32fc27be8ccdce132cc35bbc88f84fdf61b255139a430ffe0d3e1cbbb23dadb41a06013a22f09").into(), + hex!("8917fa01c4b5e52cec29d7ae709425e3db74d6692effdf857af3acf3edbe70280c9fcca6fb5ecd136ec435ba276ebc43").into(), + hex!("a9a06318af61ddc0065da1a28f42eeedd55406ac57b034e5ca861db67e21b507895b67e50ff57f5d5a6cb6ab5ead851f").into(), + hex!("b705b1fc20e7d18d681770db7d70cb382f0a6a3a11efb6200df252a5dc5b5ba8a3c02428325f439128320f64c11d1e37").into(), + hex!("86e625fadecc7a851fa55100a99eebc3f6cc9b343e706157ec6f9889eb570eb9c778d3d9b09a4f776cb1533f247ed5d4").into(), + hex!("b456e53084a2c16af3adafe492af7403b9da715abae50a32e3c12106ac8b62a86e5227895630caa7aee9bef09ed82ce2").into(), + hex!("b854b180d9b6a0e3b6d9bc1e6ea753a4034a3e7257ac877722a03cfc8ad1352189b9d80495cbe1acf57faf3c6af736e9").into(), + hex!("847d8afc70b99c7a3415a6b1e12f63549a662f155a2c7600ad7ef58a7695cccc33d601ef8465ab4fe9dd45b6116273ca").into(), + hex!("b8ae5c4d86c9bd469279fe777a04813eb841b48e6704be419be4e5714ed925c49a03e4d531918c3234c9b83f0a9dabdd").into(), + hex!("a5a845f478fbe1b4a65c111c3dafe048200cf68988278341c05329a18803e926f17add469e34622b69773548b028343d").into(), + hex!("96d4ed77545e25985b8d5d07762a548e1e83e69f6ca940ae4ac70031c979406646ad724a8b20c7493f340a686b4206b4").into(), + hex!("a8b823d4aa3635746feed04b2a7f852359e39af75c7da99b08784346d43fbc7e62da5d94b853c6407e5610321cff211c").into(), + hex!("a4ee2437e0e39982a3d20c53aea2137ad474c577f1eb215f055e340c1e4e722ff021890874c0c5de3c44ec9f57c4f4a6").into(), + hex!("917e704591d38cdb2eda70f064dfd0fbe3e80d0ad9cc2ad514c674f258c6a589609e5163cae4ebccf9d3463b1fe1cace").into(), + hex!("82fcdec7c8df977d89fdcfc66cad099c5df5cf8cc4f2c57acdf87f8f60f30a6715054b55319e56f27e896cc33b07dd4e").into(), + hex!("844ffde9768ec0432b00168366f23159e92ce7ac7b4587f65d50a011447b71bec12f5ad2095bdb04e5af933822b32bb2").into(), + hex!("a9b855262d4c32dd6ae0f7350a1b95dc4cdf0e08bca8cc14a3f58b2f49653540a9725df513bf57dfcb6efedd8c60c434").into(), + hex!("b417292b88d5ea0dac1fc361cd3597ad4a613ca481a702c034a04797e2e7b8e67b08057df8be7f2c014310728055234a").into(), + hex!("aafc0b9636bd2c8cb2988984e355b244e69ef81d7f02b2d00a71556a96b8e25210a2d3cb0bd0977c39829750a2c025dc").into(), + hex!("96e647d8278c87c6a2edff20681cc87731f8f594c305c4621fd1ca007d195b2a4a081850e9d5720a6f8c4e71d4f4c1d4").into(), + hex!("90ee25d10d400fee5f9d0e1f53a194985e7c39a9a90ed760aae850114210d653cba6d0ed7dd8874da7dc3a4bb4a98de9").into(), + hex!("8c9f0e64d1c4b6deddbc4b87e27d45d24135655bc125b5fdbb07ed226f6f3398500a6aac5ee6ef8bb7ddbd7d15f049fb").into(), + hex!("afce2866c197df192a9e1e2ed35d11b72dd6af6f2d5ee569ec6a395b1d24959a7fcdedee86f6e61a2aaf25f9ec4e6287").into(), + hex!("b901423e7f00267bfb95d656e5d031e31eaf010254eed449d04a1ea16fcceed3d88bf5fb1b905523972c70111ddb9c19").into(), + hex!("84ea93629e0a08d5f1f7b78c6e8fa8f349f8a41a45bea578232b2a09fae41310740c899a8690cad9eb2fb1869c1ddf6b").into(), + hex!("8d6dbbf76d38b60db25aa7610ec09c2acd07b28670fd23ce4525a59e1b6285ac7a4ebefff1888520a0727c48bb9f7725").into(), + hex!("9953871b114d2668fc42ade7df3b5fdb3518e9c5edee89cc26a996bb8e334a08210118238cf58ad1df6af4313311cad0").into(), + hex!("92f3e734a821a94a17809816ec57da913807cf519d3531d77a1a2cbc87d1cf38d7f35ceff7672e2763a9f15401574b80").into(), + hex!("8c8db581951bd429c9f89807b3f412cee89b64b48474d56d58ae61969b9e99d85ed28b67bd1260fa484946b0897576fc").into(), + hex!("ac272379cb0ec338155d82a4a46a0b617d3e0bdc0332a674d2fdbe2ed864262d318885cf4f02bc70ac3f8dd5aba760f0").into(), + hex!("a1a97b910f845bf4e53799b0b5cebb7fe5f23f4642b0b1b5f2d91cc646a4fd06ee5b1dd47162367f004abcd11c88c6b4").into(), + hex!("883f1598b4e93d4d62e2f1cdc5c2f1fde6f7a2564bfc1a7525f1e6ac23ea55c1e1f08d6ffcf0974361ca6e0cae124c75").into(), + hex!("a5da8ddb649b34f97876db97ce7093d9ff8302a597df9991889640581e937dce5520f627c25d06f54aea61c6181a4617").into(), + hex!("90a7b8f4f7733ecfd9ac5cb3ac50f099fa64bdd58da115b829ed3a7ad44903214d867f9554fb0649183109a648b1d1f1").into(), + hex!("abfe409b2dd4f3d5c128a84d702bb5557bd947a6bfe1df0de4eb8583765f930ab463be6824d8faeeec4e336a85cefc50").into(), + hex!("8dcf4b90176908f2d4bbadcef60023a7287ffa1f6ea9a489e8aa5dbab2528d69115e8188e0e0732944529b26261cc5be").into(), + hex!("83176c4e029cf18faba49bb29a01b5619f35487257629f14641d48bfbfaa2b281e3acd3b20b874afaf8f5ead4caca87f").into(), + hex!("995e7da9f84ec5f2f06dd5565cd8e1dab076bfd4fbd81c1fcb4524b5aaeb69444c5b244a0edc882daa82053f3e91f3a6").into(), + hex!("97f9104594fb2396206bdd28fa3494a60f39ea388515b614438d431bb818971008909a53df8dac673750293d61058bbe").into(), + hex!("8d4bd33101a0d3140b5d9635d365039343a53b756dced6f220f283d6d34934f7a72693ed8763a911a24233d8fa574410").into(), + hex!("827e028c39da0db7f2ec8c5354caa02c85d66c2dab73165ca8f69de3e24c7588703e340d799fd4ca7fb861813b2b9b22").into(), + hex!("a664423e7b42695b5d8a103535120afa07c7571641053dc9197e039b53e52ffcd73c91267342f3c487884f7e03930dbd").into(), + hex!("b3ea5ed13cad837179fc5cf68392b6cd7aa350622e61e9ad7b9ed2edc688608002d15af9d167334b41030df2ae49b6b1").into(), + hex!("8943ed4e9040956ecaff90e068148bad1148d851b6c837d1a27ed6d199b6f8e2bc76d778d4bff65008d4a5163306a638").into(), + hex!("83446ce132da2bff6a0768517a7e8bfd50fea784f08f5613589172568ce6030eecc450b82dbba91ff394a409871d39bc").into(), + hex!("94c0f309f0553738a6bcbb0e2c5531217a4271070f31cfd57932a4a8ddd469d64e266f501ea39a974d6aef9bb748c8a5").into(), + hex!("8e5302f71fff61ecab45c2b3f9bf40ff54c73277ab5ef88872342cdc9069fa0a7ba85bcb22b3ac0b14db6e415de80eb5").into(), + hex!("8f2cc48b400ad6aaf8b04865cb3560e370944cca1a3f56a210858f5460d1d1670e88e1cf02c5ee0c6d447ca514044922").into(), + hex!("b6aa597081daf781516e45928f8801a4e5b966de6e1dfd7484953d949a47eecfe32d0459411b6fabb4562c722666a9e1").into(), + hex!("8cf02871cbdcc49ed5b2d35e511beb435408d304fcbd5977ea530a5868f4dda9f3ac562a26a4e121c375414e72493c32").into(), + hex!("ae6a21e1899936603890416562fe331210bc76972666e30889fb478daa750a9737f60a309c5135f35305621be2275d8c").into(), + hex!("8f8b7fdc9e0628d27beab637b3d9567f0971032b21780822271e05e1207c229001ba0ed8c21f00d3a00c842ffc89f111").into(), + hex!("b377717e41274615d5695d2950243815975347517fdf6162c8dd1fbd2f8e4e501acc836ef7da663fbf3a3d58ca5970d3").into(), + hex!("ae7847f11a13d8d0d963e36f107e5c62c5417def636c5a9dc4c4a152ee6fd7d5c4e3fd3c58d04860fff49d5662593533").into(), + hex!("8136baa7f2be7b5d7a614b79e758765bf0530b775a50cf3bed866543abce24c80366f306f83989337fcc07833de4dd9c").into(), + hex!("b2a4daac57e91f306f1e8848a90d40b618994206075c684e5e99052ee57e69a58dc7d724de69dfaa9155f85beb10beda").into(), + hex!("883f24d44c1ebc8216ed9112e028dbcc24fe7b2b4e63ed883c11d622f01f3d24587a51a956fe9ba63ddf2147cab099a0").into(), + hex!("8215479e70e2db2437c4676a321200fbc376b1af5f8db042800ea84f54188077dbf11e62bc40d2557b09f1e29bd0632e").into(), + hex!("a734da0e7238da01b92ab746900aafd7c109b02100d5da15fd1b1be5519bbc3ab12094c7453cdd9ed84080a4e6c27911").into(), + hex!("8f81da74f90275581520ab11183775ba53cf9b4aa2913dcdf8b6f7da0b9e9ca6a9f434852a8bbbf2becc4533f8f837bc").into(), + hex!("84f3fbe3d5dcdb6dd8f4651deb9c64ac4a37bf8307472620687e21b2bd2729a00d5c01eb0dfc8367762509bbeebba8b3").into(), + hex!("8e30ac7cf94d001d54c87e6019c9a52fcc48ffda30f30f50f00b6a6e8a9d556dc66f38c24dd04f32855f5b82931ddf02").into(), + hex!("84aa1c4753031aed06b4152e8747774b1fc2e1445d427c715c635ae61332a97389e74f82431e9c32c8926c96d90d486f").into(), + hex!("b2013d8544f52f0712f509921fa14f570800c0bdb6d0bcc3676a2d0b088bc5b037b17a6403af95bdb278c653e6abd81a").into(), + hex!("a08f6596272cc5b9f31ed03bd4643d1ab6d81597b97bd08b4eaf26d5b88ce7e975eadddc052e3c8356a14cc969d729b9").into(), + hex!("9008e9a281ec8826660727d91f28011f773c3c67b94149ca87319b4dbe8b3b1e119388abb8645fe7a78e9c753d77b68c").into(), + hex!("92b6d194a8b9dc6620307d477746f5999497f88603b6c34810fc2211aaab8e83fdb558260c8a412b83e3f76fbe02e66a").into(), + hex!("b20808cefb8c9a4f072deca89227e5e062c4e9699eef9d1b1469af34bdaba32940d3031ef8a9df121fb8b6583bcfba95").into(), + hex!("b3e54b420193693f5f72974e0a211cd6c444450bd759a0c45bd45884a5ffe9220fb511b5a5cad9d8c06f7b3261ff274b").into(), + hex!("a49c01757236c8c479f67ede70d6280442e21934d0238ed43ee32ea45cc92bfef88e9374eda24d5b5f099b4795e12aa5").into(), + hex!("9661c848caac46b077a7ddd315653fa63cc00753a7a5c3eb37b9320b0978c529fd21dfef3eb6b210cad852a625817efe").into(), + hex!("81128b906a5430852af88b7031331112c1635b8149a8ae23254093aac7e184dbdeaacea813a7db37e56dfb383ffb4f7e").into(), + hex!("aac616e94d1e5dcdbdd304d658b8cab30efa6f9ce09a017e9a1369449c370a646af810c3796480a71877b5ba207f57fd").into(), + hex!("a430abee01d609ba5bbebc03c3f35eac287f6d0017b772873ebca7abbcb4b0de71bb97f0e6c8a8f7dc895248b4219cec").into(), + hex!("ad5b0a19ca0c91570a98d9baa03c95b2547070bb4c9b0ecd0cb7e03611e6078dd08c74bd4c0af27371274bc37d797679").into(), + hex!("a0382a948e776cf79846e6ad6e55ca349ec4ab37ac73d330240f832aee60cddcdc3df59083eb64bb2918eb19057c5b30").into(), + hex!("a1653c5477ed2d6c1ab9f1749ebe8162845622eff4a5c62924c729d75bf2f1bf726dead3100472592ab97c51c7c6c377").into(), + hex!("aac10f3e865b243d228f47d267e557982b0cae86356397fa00ee9c6737072d206bdb80c6b73d7671eb7d0bc9ed848d10").into(), + hex!("8fd577ceda8df32f955e9f923f018c8d89f566a35dfed17db2f935561896bc2038f285632344517850104535b004dc4d").into(), + hex!("98738e1c4e47de7eb26bc5bbf03d27dfd6c9db64a760f61b5b002c0a1d39735f0576ba7c0de6423c6094cb525c2a5526").into(), + hex!("92bc528520106ca6f0f03c326eefd83c6c1a8f0cce6bda4aeb085682b185801f821a001a8832f3eeac1351d88deb2b24").into(), + hex!("a1ae3ac5fcae99769c4cfcf44fd05b745af658272eab42171a7a56d5e4639449122561a10c33d3fe87682eb285c902a5").into(), + hex!("b8301ace0eec14790c69138a3e2abf832ecd19ef51d53e9a3533c22c7395bff527b924cca3bbbb68e48a05d8e10d2d03").into(), + hex!("b8550f77dcd382d38199aa57deb198ee70b7a7c191c42792a6ebadbc42834cbed59009c70bde1efa8d5b8d416c6fd165").into(), + hex!("a8eb958090ba78e105955e035b1efbc72323425be8c9ec7545a09a3953482958036dfcf234af75fd80308a2f88849507").into(), + hex!("b92036fa047de39e78beb2d1012e758b5e8b37e840e7f95f2e2dd6b1fc3f0c38421c8e0675e941334ddaaf40f63bfaad").into(), + hex!("b56e42e5e8e37de1298bf16b0985c04f0ea06b1eddb9599f8a6241477e86db8121efdc7b6df94bcf8485d1f66105c3fc").into(), + hex!("88d916225d642b5df09715e71e40c9df6e8cc81d6f0dac19b10ae959ae28fa24c127f6a092c6a3a5a908fdf27d7e2f77").into(), + hex!("8ee3ce0081fc1dab6de187d95386aa1052c8df23c5aeabdd5b49be430b0bf41f2265078c8a9c5efc3ed93e9e43f479ef").into(), + hex!("996aa87cb94988ca3cc7d4d60a3ee98a76629ec53469cebfebea77656be602f5c967607c7f4cb619937e54bbf204b5fa").into(), + hex!("884c6357631a82dd8a6066fbb10e0b8829c3afeb2a6fb9beac0275c318efbff605ad11a472949ed7d3c3870ca7848cc6").into(), + hex!("b33d01bcede933271a51d0328326af53c787dba341aafa31c219beeeb90bbbf73f7b2184222e6b85f8c780841840d31c").into(), + hex!("873e0f1afb2d5190d0f2cc9287072fec1f4c385172517153098c9604d5de425a2a3280e3a7884c6ea5c17cd28d75ede1").into(), + hex!("811277087dff3e3d12a0badb6c47fefa9a3404be343c825b1732675b9b56026d581c72b82759c64d5a2b6b58efa9d221").into(), + hex!("90c00fbe0cc529bcaf31757488a00a4548813bd3101254dad824819a69e2fcd9df39684ffdb25b46406d35de66080ea3").into(), + hex!("b31b53d46ac3b917dc019f1676236e283ad579c7c6cf4d855fe84cc11a5af64b2267c00f7682d34e4939ada56b8ee472").into(), + hex!("940b7d2d0fb1c51461d325413b0aed1ca5ccb250225da7b73a4356c015f243b04f26f19d4eff69fdf34f6c5d38234176").into(), + hex!("92cc69a2ddd1927a202bd32a3dc2c5013832caa0255447bf093718c9e3b8e4f6fb4614a413945570075878d872e94a17").into(), + hex!("862e3e58502643407e60af51b6b59508af13aefd35d2c25164c14545159a187551b99eebb451ece86141926e9f0a97ad").into(), + hex!("847892e2c1b78b37abec4c1be99d50c5549f1f9d133dfcf2fd19fcc0e79f6642279583f8cfe3ade58030de16ad739d70").into(), + hex!("b34e630870646a9a7115ed17a04dcfa8bf1c7d682012faa0246924752d4ee69608f246dc93cdfa9d67e64039cadd88a3").into(), + hex!("b3ddcbca1d25d3e79c4dd99927387ceddeb502799ebfb3d3013b9b1b12fcba8b4019b9ae66385d1a6bf6a8531f29d889").into(), + hex!("86156644b162d2a08701093207c3db3a5215c3fad3d68390099026d72f81cdcb2c32c597679774d1eb062dfdd2d17012").into(), + hex!("ac98d20d2ddbf9a5090de3070ba819a6b5373634d05284cc8465232e16fbeca6d2c9fb18108f5403eae84ff672877ec1").into(), + hex!("92abbd517f3c272eb3066ac3b1b13f65d72f629eb7472c626222521a06b3bde1c83f0697d91ba57b913fec3bb3d62121").into(), + hex!("b46713590d56cfaf609be10a806b5716e66474178bbd7f4eda2c851e3ca15db93daa4a6b0586580bb7620b4f24e76bb5").into(), + hex!("a10ea0d855f6d2fa3c3930b025a0018a04512d4b7f8738e45462f4d512061a9751926f18b5694ce71630e02486e105ef").into(), + hex!("ade8c2670394a8c4301c701a60490400a0a6e102d0ac85ea8cbd18cc7318378a2f78dab403195794ecd8b70d6188f5fd").into(), + hex!("9307c8b5e1629ef75446f5d7c113a532a178634ac5b6f1104bbbab90e14af25e1ffc50c9d15d62a1047edb8e57e720ad").into(), + hex!("89e32142a5f37c579c95789e742f66d941a5c3b0aadae810cc02985ee64456f3f9830addb60de4b56b71a7f3eddbba62").into(), + hex!("a58d4ff293677af4d0fc1c577a77675a9072fe7fd42621c2713f0a6455d2e72b0eb68586da1ea83f1a772ecf036ec0d6").into(), + ], + aggregate_pubkey: hex!("a65ca267854f7725ec07e57782c3f41035e52ea68a909a9d2d36ae2c082932ee0dfa8162e5a3145f0263453abd5b1ac6").into() }, next_sync_committee_branch: vec![ hex!("28bfcd34b4a658a55a6fecf00126c9a3f7e468bbf76ac08af1472016c9903a81").into(), @@ -1086,7 +1079,7 @@ pub fn sync_committee_update< hex!("b60e37d82e54a164d6b9b378263bc45867aaf832d39e587cebf7b681c8aa7b79").into(), hex!("e9a165f4e79b941d1715fa7a6c53fc2ba39e0117595dd6e0b6b6fc7232b87e9f").into(), hex!("57ab39187e2342690b3cf5722cc7f9b98655c5433b03907e0064c8b0a5e652d8").into(), - ].try_into().expect("too many branch proof items"), + ], finalized_header: BeaconHeader{ slot: 5217920, proposer_index: 209021, @@ -1103,8 +1096,8 @@ pub fn sync_committee_update< hex!("57ab39187e2342690b3cf5722cc7f9b98655c5433b03907e0064c8b0a5e652d8").into(), ].try_into().expect("too many branch proof items"), sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ff7ffffdbffffff7edffd5f4fffffd79ffce7ff7dff6ffcdefb9fffdffff3bffdedbffbf7fff9fdfe7bf5dfebfbffeffffe7e1fffbfeefeb77bfdfa7ffddffbb").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("a58417f897521dc58fa339c9465b1346a7005251ad582fafae984918606005b23627eface374912c70e4ed28c4358eca03783419e3625ab1159b9562837581c6647fc960a6a7d54b0a811b1d5af853ee8274d9023a195f14530d46b8f6af07c2").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("ff7ffffdbffffff7edffd5f4fffffd79ffce7ff7dff6ffcdefb9fffdffff3bffdedbffbf7fff9fdfe7bf5dfebfbffeffffe7e1fffbfeefeb77bfdfa7ffddffbb"), + sync_committee_signature: hex!("a58417f897521dc58fa339c9465b1346a7005251ad582fafae984918606005b23627eface374912c70e4ed28c4358eca03783419e3625ab1159b9562837581c6647fc960a6a7d54b0a811b1d5af853ee8274d9023a195f14530d46b8f6af07c2").into(), }, sync_committee_period: 636, signature_slot: 5217992, @@ -1115,15 +1108,11 @@ pub fn sync_committee_update< hex!("eb4d119d9984d9807f208b0fa6904743146b9ec4a5f049102ce666d4bbf9129e").into(), hex!("77ed1405a1f56b514112f01904b5785290a4b2eb7a811421d9994c99df192833").into(), hex!("7548ec8105fbbda4f6d8a541041f763f440dac452a94d95d4e1c4f193e1065f3").into(), - ].try_into().expect("too many branch proof items"), + ], }; } -pub fn finalized_header_update< - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, ->() -> FinalizedHeaderUpdate { +pub fn finalized_header_update() -> FinalizedHeaderUpdate { return FinalizedHeaderUpdate{ attested_header: BeaconHeader { slot: 5218079, @@ -1146,10 +1135,10 @@ pub fn finalized_header_update< hex!("7044430095fdbc4ad8ac502b16a072033866b358e714b8f1aeef8a1dba877ee3").into(), hex!("94a1240615f12982a99695ce6a585c84b7bf5bb3e91bfe9c8e0fecd1e7b3fc78").into(), hex!("167b6c116688945f147dce2aa07caea7b789ae62dbd6acd1ec20ff80f7906b76").into(), - ].try_into().expect("too many branch proof items"), + ], sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ff7ffefdbfffbff7edffd5f4fffffd39ff4c7f77dff6dfc9cfa37ffcfff73bffdef9fdbd7fff9ddfe7bf5dfeafb7fefbffe3e1fffbffefef77bfffaff7ddffb3").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("913b42b97f616f46b2e5cfa2507e27373caf95d88a0248d263968a58bca502a2d144e66aca766750d834d96ecce38dec04c84613734441d5358c2fb5b83a8248ff1b713e87248b5729a84e1f78495accc0fc030afd540e59962ef597f101b8c1").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("ff7ffefdbfffbff7edffd5f4fffffd39ff4c7f77dff6dfc9cfa37ffcfff73bffdef9fdbd7fff9ddfe7bf5dfeafb7fefbffe3e1fffbffefef77bfffaff7ddffb3"), + sync_committee_signature: hex!("913b42b97f616f46b2e5cfa2507e27373caf95d88a0248d263968a58bca502a2d144e66aca766750d834d96ecce38dec04c84613734441d5358c2fb5b83a8248ff1b713e87248b5729a84e1f78495accc0fc030afd540e59962ef597f101b8c1").into(), }, signature_slot: 5218080, block_roots_root: hex!("b3e5c7b3f91cdabd828405dabc3204fe1afeaba4c326eacfbe04d73d39a21606").into(), @@ -1159,25 +1148,11 @@ pub fn finalized_header_update< hex!("96ad2c8032ebe6b90c6c7b0b9478bc28580ce9a87021929d1883a7b077d0f8de").into(), hex!("143bc147ead46049a0ac8ce1854e80a8b8a35d94ac08796dc2d14051739b49a4").into(), hex!("a87a247507ff0825f9258ec57ff222ef8ee684fe770349e955210c736ca7dad4").into(), - ].try_into().expect("too many branch proof items") + ] }; } -pub fn header_update< - FeeRecipientSize: Get, - LogsBloomSize: Get, - ExtraDataSize: Get, - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, ->() -> HeaderUpdate< - FeeRecipientSize, - LogsBloomSize, - ExtraDataSize, - SignatureSize, - ProofSize, - SyncCommitteeSize, -> { +pub fn header_update() -> HeaderUpdate { return HeaderUpdate{ beacon_header: BeaconHeader{ slot: 5217982, @@ -1188,7 +1163,7 @@ pub fn header_update< }, execution_header: ExecutionPayloadHeader { parent_hash: hex!("65fc36cc6d592812fbaa2c6b7e79c0950d8cc0d2180dd5f664d95175ac9fc587").into(), - fee_recipient: hex!("e0a2bd4258d2768837baa26a28fe71dc079f84c7").to_vec().try_into().expect("fee recipient too long"), + fee_recipient: hex!("e0a2bd4258d2768837baa26a28fe71dc079f84c7").into(), state_root: hex!("deb37074e1c428a502533236f8489ffc80debc7963aea6346867aadbe0d120a4").into(), receipts_root: hex!("e951758cd9e61a3a90d7d2fdbc89c1afad5b51e2e44a989c904ca97cf4ddfa4a").into(), logs_bloom: hex!("002700c2010000420021040080806080000901002010000000092014080001044030100000080a06110400000100008001844000000220e24600ce8c81242042021140049c71800cca10000b402192642a1600048120f4008072818a808c108000041100022050008411102404a00801002a0e1000014180d0a00610800c4250511c20220040010a204e08108231002a212006830814010e6404014814028214421e00111002000921101002990002002024261a2807020081080108282013020931414601808408040000010589401441489000110800900201611014062b00803010a120400a04a00100482800089481011058084120420002890805000845").to_vec().try_into().expect("logs bloom too long"), @@ -1197,7 +1172,7 @@ pub fn header_update< gas_limit: 30000000, gas_used: 11572733, timestamp: 1679123784, - extra_data: hex!("d883010b04846765746888676f312e32302e31856c696e7578").to_vec().try_into().expect("extra data too long"), + extra_data: hex!("d883010b04846765746888676f312e32302e31856c696e7578").into(), base_fee_per_gas: U256::from(6589888698 as u64), block_hash: hex!("6c4d734572bd098102736e6f61dc9346601180255d92e3a18e43e681dfbad188").into(), transactions_root: hex!("e40194988e1524402fee76090c24f6ff5bb91b4765c5fbf5caf954b8848d86ee").into(), @@ -1210,8 +1185,8 @@ pub fn header_update< hex!("6fcc83169ef7b54eb9af29f63890644ac3fd1bffeb6edee8945bb13d9df802e9").into(), ].try_into().expect("too many branch proof items"), sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ff7ffefdbfffbff7edffd5b4fffffd39ff4c7f77dff6dfcdefa17ffdffff3bffded9fdbd7fff9ddfe7bf5dfeafb7feff7fe3e1fffbffefef77bfdfa7f7ddffb3").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("9642b8a94e17eff18c50b1e0603e062fd7637e121d34a4a91e5ad48a9b8076497909de6c9c8e61980a5b33fa6f412d9519bb6f710f0144dfddd01eb36b18e9109ff7cdabc40752d15da22371214189320bc7588090ce4bfafeaee84972f4c7cf").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("ff7ffefdbfffbff7edffd5b4fffffd39ff4c7f77dff6dfcdefa17ffdffff3bffded9fdbd7fff9ddfe7bf5dfeafb7feff7fe3e1fffbffefef77bfdfa7f7ddffb3"), + sync_committee_signature: hex!("9642b8a94e17eff18c50b1e0603e062fd7637e121d34a4a91e5ad48a9b8076497909de6c9c8e61980a5b33fa6f412d9519bb6f710f0144dfddd01eb36b18e9109ff7cdabc40752d15da22371214189320bc7588090ce4bfafeaee84972f4c7cf").into(), }, signature_slot: 5217983, block_root_branch: vec![ @@ -1228,7 +1203,7 @@ pub fn header_update< hex!("744dffaab90eca8e92f66b165d4523d5899a33e25663d956b73022a2f4213a0e").into(), hex!("f3b04813e6897bb1642c1c42f1edfdaf8b00b2b1b57d567e512dc1c5d51660db").into(), hex!("8795c1259089af496aa6339978f58f2fe25f89225dc97dd82dd0c3739fe94d10").into(), - ].try_into().expect("too many branch proof items"), + ], block_root_branch_header_root: hex!("52c9f5ef64da062dee00a30ebe16710a3ffe59cf91eedf96a69ae5d198d7d982").into(), }; } diff --git a/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_minimal.rs b/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_minimal.rs index 0b3c33526..8ea42907c 100644 --- a/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_minimal.rs +++ b/parachain/pallets/ethereum-beacon-client/src/benchmarking/data_minimal.rs @@ -3,17 +3,17 @@ use frame_support::traits::Get; use hex_literal::hex; use snowbridge_beacon_primitives::{ - BeaconHeader, ExecutionPayloadHeader, FinalizedHeaderUpdate, HeaderUpdate, InitialSync, - PublicKey, SyncAggregate, SyncCommittee, SyncCommitteePeriodUpdate, + BeaconHeader, ExecutionPayloadHeader, FinalizedHeaderUpdate, HeaderUpdate, InitialUpdate, + PublicKey, SyncAggregate, SyncCommittee, SyncCommitteeUpdate, }; use sp_core::U256; use sp_std::vec; pub fn initial_sync, ProofSize: Get>( -) -> InitialSync { +) -> InitialUpdate { let time_now = 1675679352; //2023.2.6 - return InitialSync{ + return InitialUpdate{ header: BeaconHeader{ slot: 152, proposer_index: 2, @@ -22,41 +22,41 @@ pub fn initial_sync, ProofSize: Get>( body_root: hex!("d0ae6720fd5cd20d994292f4efa540811f2011b4b8aa466fe1a3c6aa8b1418ad").into(), }, current_sync_committee: SyncCommittee{ - pubkeys: vec![ - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into()) + pubkeys: [ + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + ], + aggregate_pubkey: hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into(), }, current_sync_committee_branch: vec![ hex!("ae55686c9aa0cfc3a6a3edf5fcc27f3eafbe2772444f4fae6f1f00e1cee7d0ac").into(), @@ -64,7 +64,7 @@ pub fn initial_sync, ProofSize: Get>( hex!("24851e4e01f264323b3bf1373dc8c99c71afa12ec04329df98e6dc1c45555365").into(), hex!("f5097ceea15bf7a5f7eabcaacba29af64ba0653e2077287e1d17f98d1a5778ad").into(), hex!("ebd5dd152ab8fc8acd6ee0d7e43537c3caedc12a9e283e9079ac17a92f2eb931").into(), - ].try_into().expect("too many branch proof items"), + ], validators_root: hex!("270d43e74ce340de4bca2b1936beca0f4f5408d9e78aec4850920baf659d5b69").into(), import_time: time_now + 97200, // now + 27 hour sync committee period }; @@ -74,8 +74,8 @@ pub fn sync_committee_update< SignatureSize: Get, ProofSize: Get, SyncCommitteeSize: Get, ->() -> SyncCommitteePeriodUpdate { - return SyncCommitteePeriodUpdate { +>() -> SyncCommitteeUpdate { + return SyncCommitteeUpdate { attested_header: BeaconHeader { slot: 144, proposer_index: 2, @@ -84,41 +84,41 @@ pub fn sync_committee_update< body_root: hex!("8624a57d021cf59e367432769b53e4da63f9a613db778e2e89db701f0b068bea").into(), }, next_sync_committee: SyncCommittee { - pubkeys: vec![ - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - PublicKey(hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into()), - PublicKey(hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into()), - PublicKey(hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into()), - PublicKey(hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into()), - PublicKey(hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into()), - PublicKey(hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into()), - PublicKey(hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into()), - PublicKey(hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into()), - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into()) + pubkeys: [ + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + hex!("a99a76ed7796f7be22d5b7e85deeb7c5677e88e511e0b337618f8c4eb61349b4bf2d153f649f7b53359fe8b94a38e44c").into(), + hex!("a8d4c7c27795a725961317ef5953a7032ed6d83739db8b0e8a72353d1b8b4439427f7efa2c89caa03cc9f28f8cbab8ac").into(), + hex!("ab0bdda0f85f842f431beaccf1250bf1fd7ba51b4100fd64364b6401fda85bb0069b3e715b58819684e7fc0b10a72a34").into(), + hex!("88c141df77cd9d8d7a71a75c826c41a9c9f03c6ee1b180f3e7852f6a280099ded351b58d66e653af8e42816a4d8f532e").into(), + hex!("a3a32b0f8b4ddb83f1a0a853d81dd725dfe577d4f4c3db8ece52ce2b026eca84815c1a7e8e92a4de3d755733bf7e4a9b").into(), + hex!("81283b7a20e1ca460ebd9bbd77005d557370cabb1f9a44f530c4c4c66230f675f8df8b4c2818851aa7d77a80ca5a4a5e").into(), + hex!("9977f1c8b731a8d5558146bfb86caea26434f3c5878b589bf280a42c9159e700e9df0e4086296c20b011d2e78c27d373").into(), + hex!("b89bebc699769726a318c8e9971bd3171297c61aea4a6578a7a4f94b547dcba5bac16a89108b6b6a1fe3695d1a874a0b").into(), + ], + aggregate_pubkey: hex!("8fe11476a05750c52618deb79918e2e674f56dfbf12dbce55ae4386d108e8a1e83c6326f5957e2ef19137582ce270dc6").into() }, next_sync_committee_branch: vec![ hex!("9aaac2741ce2878a681113933945f318219d798b6d487cc93e8754a2a5a3a965").into(), @@ -188,8 +188,8 @@ pub fn finalized_header_update< hex!("e814c498f7b604b0ee9168053bb905fca91d004c1cb5cd5e8647ce7ceb4328c1").into(), ].try_into().expect("too many branch proof items"), sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ffffffff").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("b7a1aa69fd2b57308f871dc877215b3521ad336b5af88bc286c5b42f8ecf36cad076c67465fc5c02c72132ee000eeb300e60362fbd5548a6c27e5b0b8d0d3d6b32adfc08673605572b630b005ac07af5cb7617176100ae843fbb86cee4e7c683").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("ffffffff"), + sync_committee_signature: hex!("b7a1aa69fd2b57308f871dc877215b3521ad336b5af88bc286c5b42f8ecf36cad076c67465fc5c02c72132ee000eeb300e60362fbd5548a6c27e5b0b8d0d3d6b32adfc08673605572b630b005ac07af5cb7617176100ae843fbb86cee4e7c683").into(), }, signature_slot: 169, block_roots_root: hex!("0ca0cf2867bc9c8361f2c66a926218d0a5817301667e0a974983cd1d87dd6e55").into(), @@ -199,7 +199,7 @@ pub fn finalized_header_update< hex!("314eb3af46fb3cd5b6e78ad4e91467a4149c056d1e8d8e76dd2382177d2be464").into(), hex!("bc5b324e321445e9ee98c670c563a5c7793b12ecdd79b25be0abee5288d9b410").into(), hex!("c1e6c27607e2ec00b123b5e98426100fe38c14e35030505e9cd5c713f194c71d").into(), - ].try_into().expect("too many branch proof items") + ] }; } @@ -237,7 +237,7 @@ pub fn header_update< gas_limit: 69094400, gas_used: 0, timestamp: 1679133094, - extra_data: hex!("d983010b02846765746888676f312e31392e358664617277696e").to_vec().try_into().expect("extra data too long"), + extra_data: hex!("d983010b02846765746888676f312e31392e358664617277696e").into(), base_fee_per_gas: U256::from(7 as u64), block_hash: hex!("d84d6e83a9b4783fe4a290edc0d57e218a42aeb4f4c97dc7c83dacf82a1ec5eb").into(), transactions_root: hex!("7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1").into(), @@ -248,10 +248,10 @@ pub fn header_update< hex!("336488033fe5f3ef4ccc12af07b9370b92e553e35ecb4a337a1b1c0e4afe1e0e").into(), hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), hex!("1b1451ad43516084cc488a22800d39d3368f0220cbc844957321fdf4dfe8154d").into(), - ].try_into().expect("too many branch proof items"), + ], sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("ffffffff").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("b203cba9326023622caad739fe44a50392d85a8bc1cb3f0c64d89319a865dc1dc1d1ff318d939ac24e4866068d8ca442116d4e7badec88015fd2865f97d5d5ab321c6c9a6994a9afee31f03cd015131320324bffc5d18746d232578c321ea61b").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("ffffffff"), + sync_committee_signature: hex!("b203cba9326023622caad739fe44a50392d85a8bc1cb3f0c64d89319a865dc1dc1d1ff318d939ac24e4866068d8ca442116d4e7badec88015fd2865f97d5d5ab321c6c9a6994a9afee31f03cd015131320324bffc5d18746d232578c321ea61b").into(), }, signature_slot: 151, block_root_branch: vec![ @@ -261,7 +261,7 @@ pub fn header_update< hex!("0fff87fb108fae09e61eafef5bcf22f4a5267699d5624fab371f661cc5e0c938").into(), hex!("76dd343907582c21ec28320c1d6a10349d338ac8ae4bb6e890063ad7d4ce4a6a").into(), hex!("7eebb150fd62159c1adf5dbe3e677b9574ea304d752f06de0a9f03f8f0ed6597").into(), - ].try_into().expect("too many branch proof items"), + ], block_root_branch_header_root: hex!("105976df5861b95fa4184564978eac0bcbe872acdd77a0ead552a8b283dabc4f").into(), }; } diff --git a/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs b/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs index 6b344a0a2..9d350477f 100644 --- a/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs +++ b/parachain/pallets/ethereum-beacon-client/src/benchmarking/mod.rs @@ -18,7 +18,7 @@ benchmarks! { }: sync_committee_period_update(RawOrigin::Signed(caller.clone()), sync_committee_update.clone()) verify { - assert!(>::get(sync_committee_update.sync_committee_period+1).pubkeys.len() > 0); + assert!(>::get(sync_committee_update.sync_committee_period+1).unwrap().pubkeys.len() > 0); } import_finalized_header { @@ -46,9 +46,7 @@ benchmarks! { }: _(RawOrigin::Signed(caller.clone()), finalized_header_update.clone()) verify { - let header_hash_bytes = merkleization::hash_tree_root_beacon_header(finalized_header_update.finalized_header).unwrap(); - - let header_hash: H256 = header_hash_bytes.into(); + let header_hash: H256 = finalized_header_update.finalized_header.hash_tree_root().unwrap(); >::get(header_hash).unwrap(); } @@ -66,13 +64,11 @@ benchmarks! { header_update.beacon_header.slot, ), initial_sync_data.current_sync_committee); - let finalized_update: FinalizedHeaderUpdate = finalized_header_update(); + let finalized_update: FinalizedHeaderUpdate<> = finalized_header_update(); let finalized_slot = finalized_update.finalized_header.slot; - let finalized_block_root: H256 = - merkleization::hash_tree_root_beacon_header(finalized_update.finalized_header) - .unwrap() - .into(); + let finalized_block_root = finalized_update.finalized_header.hash_tree_root() + .unwrap(); LatestFinalizedHeaderState::::set(FinalizedHeaderState{ beacon_block_root: finalized_block_root, @@ -85,8 +81,7 @@ benchmarks! { ); }: _(RawOrigin::Signed(caller.clone()), header_update.clone()) verify { - let header: ExecutionHeader = header_update.execution_header.try_into().unwrap(); - >::get(header.block_hash).unwrap(); + assert!(>::contains_key(header_update.execution_header.block_hash)) } unblock_bridge { @@ -100,7 +95,7 @@ benchmarks! { let participant_pubkeys = get_participant_pubkeys::(&update)?; let signing_root = get_signing_message::(&update)?; }:{ - EthereumBeaconClient::::bls_fast_aggregate_verify(participant_pubkeys,signing_root,update.sync_aggregate.sync_committee_signature)?; + EthereumBeaconClient::::bls_fast_aggregate_verify(&participant_pubkeys,signing_root,&update.sync_aggregate.sync_committee_signature)?; } bls_aggregate_pubkey { diff --git a/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs b/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs index 0b6c0262d..e48077ad1 100644 --- a/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs +++ b/parachain/pallets/ethereum-beacon-client/src/benchmarking/util.rs @@ -1,14 +1,19 @@ -use super::*; -use crate::Pallet as EthereumBeaconClient; -use milagro_bls::{AggregatePublicKey, AggregateSignature, Signature}; +use crate::{ + Config, LatestSyncCommitteePeriod, Pallet as EthereumBeaconClient, PublicKey, Signature, + SyncCommitteeUpdate, SyncCommittees, ValidatorsRoot, Vec, +}; +use milagro_bls::{AggregatePublicKey, AggregateSignature, Signature as MilagroSignature}; +use sp_core::H256; -pub fn initialize_sync_committee() -> Result, &'static str> -{ +use super::{initial_sync, sync_committee_update}; +use crate::{decompress_sync_committee_bits, Error}; + +pub fn initialize_sync_committee() -> Result { let initial_sync_data = initial_sync(); EthereumBeaconClient::::initial_sync(initial_sync_data.clone())?; - let sync_committee_update: SyncCommitteePeriodUpdateOf = sync_committee_update(); + let sync_committee_update = sync_committee_update(); //initialize SyncCommittees with period in sync_committee_update LatestSyncCommitteePeriod::::set(EthereumBeaconClient::::compute_current_sync_period( @@ -24,14 +29,14 @@ pub fn initialize_sync_committee() -> Result( - update: &SyncCommitteePeriodUpdateOf, + update: &SyncCommitteeUpdate, ) -> Result, &'static str> { let sync_committee_bits = - get_sync_committee_bits(update.sync_aggregate.sync_committee_bits.clone()).unwrap(); + decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits.clone()); let current_period = EthereumBeaconClient::::compute_current_sync_period(update.attested_header.slot); let current_sync_committee = - EthereumBeaconClient::::get_sync_committee_for_period(current_period)?; + SyncCommittees::::get(current_period).ok_or("no sync committee")?; let sync_committee_pubkeys = current_sync_committee.pubkeys; let mut participant_pubkeys: Vec = Vec::new(); for (bit, pubkey) in sync_committee_bits.iter().zip(sync_committee_pubkeys.iter()) { @@ -43,17 +48,15 @@ pub fn get_participant_pubkeys( Ok(participant_pubkeys) } -pub fn get_signing_message( - update: &SyncCommitteePeriodUpdateOf, -) -> Result { +pub fn get_signing_message(update: &SyncCommitteeUpdate) -> Result { let validators_root = >::get(); let fork_version = EthereumBeaconClient::::compute_fork_version( EthereumBeaconClient::::compute_epoch_at_slot( update.signature_slot, - config::SLOTS_PER_EPOCH, + crate::config::SLOTS_PER_EPOCH, ), ); - let domain_type = config::DOMAIN_SYNC_COMMITTEE.to_vec(); + let domain_type = crate::config::DOMAIN_SYNC_COMMITTEE.to_vec(); let domain = EthereumBeaconClient::::compute_domain(domain_type, fork_version, validators_root)?; let signing_root = @@ -62,9 +65,10 @@ pub fn get_signing_message( } pub fn get_aggregate_signature( - signature: BoundedVec, + signature: Signature, ) -> Result> { - let sig = Signature::from_bytes(&signature[..]).map_err(|_| Error::::InvalidSignature)?; + let sig = + MilagroSignature::from_bytes(&signature.0[..]).map_err(|_| Error::::InvalidSignature)?; let agg_sig = AggregateSignature::from_signature(&sig); Ok(agg_sig) } diff --git a/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs b/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs index e9b9b7f5f..294335981 100644 --- a/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs +++ b/parachain/pallets/ethereum-beacon-client/src/config/mainnet.rs @@ -2,6 +2,7 @@ pub const SLOTS_PER_EPOCH: u64 = 32; pub const SECONDS_PER_SLOT: u64 = 12; pub const EPOCHS_PER_SYNC_COMMITTEE_PERIOD: u64 = 256; pub const SYNC_COMMITTEE_SIZE: usize = 512; +pub const SYNC_COMMITTEE_BITS_SIZE: usize = SYNC_COMMITTEE_SIZE / 8; pub const SLOTS_PER_HISTORICAL_ROOT: usize = 8192; pub const IS_MINIMAL: bool = false; pub const BLOCK_ROOT_AT_INDEX_PROOF_DEPTH: u64 = 13; diff --git a/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs b/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs index f430c3dc3..130978ea2 100644 --- a/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs +++ b/parachain/pallets/ethereum-beacon-client/src/config/minimal.rs @@ -2,6 +2,7 @@ pub const SLOTS_PER_EPOCH: u64 = 8; pub const SECONDS_PER_SLOT: u64 = 6; pub const EPOCHS_PER_SYNC_COMMITTEE_PERIOD: u64 = 8; pub const SYNC_COMMITTEE_SIZE: usize = 32; +pub const SYNC_COMMITTEE_BITS_SIZE: usize = SYNC_COMMITTEE_SIZE / 8; pub const SLOTS_PER_HISTORICAL_ROOT: usize = 64; pub const IS_MINIMAL: bool = true; pub const BLOCK_ROOT_AT_INDEX_PROOF_DEPTH: u64 = 6; diff --git a/parachain/pallets/ethereum-beacon-client/src/config.rs b/parachain/pallets/ethereum-beacon-client/src/config/mod.rs similarity index 75% rename from parachain/pallets/ethereum-beacon-client/src/config.rs rename to parachain/pallets/ethereum-beacon-client/src/config/mod.rs index 0eb2ae5ca..d8bc59383 100644 --- a/parachain/pallets/ethereum-beacon-client/src/config.rs +++ b/parachain/pallets/ethereum-beacon-client/src/config/mod.rs @@ -1,8 +1,7 @@ -#[cfg(feature = "minimal")] -mod minimal; +use static_assertions::const_assert; -#[cfg(not(feature = "minimal"))] -mod mainnet; +pub mod mainnet; +pub mod minimal; #[cfg(feature = "minimal")] pub use minimal::*; @@ -11,10 +10,8 @@ pub use minimal::*; pub use mainnet::*; pub const CURRENT_SYNC_COMMITTEE_INDEX: u64 = 22; -pub const CURRENT_SYNC_COMMITTEE_DEPTH: u64 = 5; - -pub const NEXT_SYNC_COMMITTEE_DEPTH: u64 = 5; pub const NEXT_SYNC_COMMITTEE_INDEX: u64 = 23; +pub const SYNC_COMMITTEE_DEPTH: u64 = 5; pub const FINALIZED_ROOT_DEPTH: u64 = 6; pub const FINALIZED_ROOT_INDEX: u64 = 41; @@ -29,9 +26,14 @@ pub const MAX_EXTRA_DATA_BYTES: usize = 32; pub const MAX_LOGS_BLOOM_SIZE: usize = 256; pub const MAX_FEE_RECIPIENT_SIZE: usize = 20; +pub const MAX_FINALIZED_HEADER_SLOT_ARRAY: u32 = 1000; +pub const MAX_BRANCH_PROOF_SIZE: u32 = 20; + /// DomainType('0x07000000') /// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/beacon-chain.md#domain-types pub const DOMAIN_SYNC_COMMITTEE: [u8; 4] = [7, 0, 0, 0]; pub const PUBKEY_SIZE: usize = 48; pub const SIGNATURE_SIZE: usize = 96; + +const_assert!(SYNC_COMMITTEE_BITS_SIZE == SYNC_COMMITTEE_SIZE / 8); diff --git a/parachain/pallets/ethereum-beacon-client/src/lib.rs b/parachain/pallets/ethereum-beacon-client/src/lib.rs index f868d4c05..e3e0eda21 100644 --- a/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/parachain/pallets/ethereum-beacon-client/src/lib.rs @@ -2,17 +2,17 @@ #![cfg_attr(not(feature = "std"), no_std)] pub mod config; -mod merkleization; -#[cfg(test)] -mod mock; pub mod weights; -mod ssz; +#[cfg(test)] +mod mock; #[cfg(test)] mod tests; #[cfg(test)] +#[cfg(not(feature = "minimal"))] mod tests_mainnet; #[cfg(test)] +#[cfg(feature = "minimal")] mod tests_minimal; #[cfg(feature = "runtime-benchmarks")] @@ -20,44 +20,47 @@ mod benchmarking; pub use weights::WeightInfo; -use crate::merkleization::get_sync_committee_bits; use frame_support::{dispatch::DispatchResult, log, traits::UnixTime, transactional}; use frame_system::ensure_signed; -use snowbridge_beacon_primitives::{ - BeaconHeader, Domain, ExecutionHeader, ExecutionHeaderState, FinalizedHeaderState, - FinalizedHeaderUpdate, ForkData, ForkVersion, HeaderUpdate, InitialSync, PublicKey, Root, - SigningData, SyncCommittee, SyncCommitteePeriodUpdate, +use primitives::{ + verify_merkle_proof, verify_receipt_proof, BeaconHeader, CompactExecutionHeader, + ExecutionHeaderState, FinalizedHeaderState, ForkData, ForkVersion, PublicKey, Signature, + SigningData, }; use snowbridge_core::{Message, Verifier}; use sp_core::H256; -use sp_io::hashing::sha2_256; use sp_std::prelude::*; +use milagro_bls::{AggregatePublicKey, AggregateSignature, AmclError}; +use primitives::ForkVersions; +use snowbridge_core::Proof; +use snowbridge_ethereum::{Header as EthereumHeader, Log, Receipt}; +use sp_core::U256; + use frame_support::{traits::Get, BoundedVec}; pub use pallet::*; -pub type HeaderUpdateOf = HeaderUpdate< - ::MaxFeeRecipientSize, - ::MaxLogsBloomSize, - ::MaxExtraDataSize, - ::MaxSignatureSize, - ::MaxProofBranchSize, - ::MaxSyncCommitteeSize, ->; -pub type InitialSyncOf = - InitialSync<::MaxSyncCommitteeSize, ::MaxProofBranchSize>; -pub type SyncCommitteePeriodUpdateOf = SyncCommitteePeriodUpdate< - ::MaxSignatureSize, - ::MaxProofBranchSize, - ::MaxSyncCommitteeSize, ->; -pub type FinalizedHeaderUpdateOf = FinalizedHeaderUpdate< - ::MaxSignatureSize, - ::MaxProofBranchSize, - ::MaxSyncCommitteeSize, ->; -pub type SyncCommitteeOf = SyncCommittee<::MaxSyncCommitteeSize>; +use config::{ + MAX_FINALIZED_HEADER_SLOT_ARRAY, SLOTS_PER_HISTORICAL_ROOT, SYNC_COMMITTEE_BITS_SIZE, + SYNC_COMMITTEE_SIZE, +}; + +pub type InitialUpdate = primitives::InitialUpdate; +pub type HeaderUpdate = primitives::HeaderUpdate; +pub type SyncCommitteeUpdate = + primitives::SyncCommitteeUpdate; +pub type FinalizedHeaderUpdate = + primitives::FinalizedHeaderUpdate; +pub type SyncCommittee = primitives::SyncCommittee; + +fn decompress_sync_committee_bits( + input: [u8; SYNC_COMMITTEE_BITS_SIZE], +) -> [u8; SYNC_COMMITTEE_SIZE] { + primitives::decompress_sync_committee_bits::( + input, + ) +} #[frame_support::pallet] pub mod pallet { @@ -66,12 +69,6 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; - use milagro_bls::{AggregatePublicKey, AggregateSignature, AmclError, Signature}; - use snowbridge_beacon_primitives::ForkVersions; - use snowbridge_core::Proof; - use snowbridge_ethereum::{Header as EthereumHeader, Log, Receipt}; - use sp_core::U256; - #[pallet::pallet] pub struct Pallet(_); @@ -80,24 +77,6 @@ pub mod pallet { type RuntimeEvent: From> + IsType<::RuntimeEvent>; type TimeProvider: UnixTime; #[pallet::constant] - type MaxSyncCommitteeSize: Get; - #[pallet::constant] - type MaxProofBranchSize: Get; - #[pallet::constant] - type MaxExtraDataSize: Get; - #[pallet::constant] - type MaxLogsBloomSize: Get; - #[pallet::constant] - type MaxFeeRecipientSize: Get; - #[pallet::constant] - type MaxPublicKeySize: Get; - #[pallet::constant] - type MaxSignatureSize: Get; - #[pallet::constant] - type MaxSlotsPerHistoricalRoot: Get; - #[pallet::constant] - type MaxFinalizedHeaderSlotArray: Get; - #[pallet::constant] type ForkVersions: Get; type WeightInfo: WeightInfo; type WeakSubjectivityPeriodSeconds: Get; @@ -145,8 +124,8 @@ pub mod pallet { ExpectedFinalizedHeaderNotStored, BridgeBlocked, InvalidSyncCommitteeHeaderUpdate, - InvalidSyncCommitteePeriodUpdateWithGap, - InvalidSyncCommitteePeriodUpdateWithDuplication, + InvalidSyncCommitteeUpdateWithGap, + InvalidSyncCommitteeUpdateWithDuplication, InvalidSignatureSlot, InvalidAttestedHeaderSlot, DuplicateFinalizedHeaderUpdate, @@ -165,7 +144,7 @@ pub mod pallet { #[pallet::storage] pub(super) type FinalizedBeaconHeaderSlots = - StorageValue<_, BoundedVec, ValueQuery>; + StorageValue<_, BoundedVec>, ValueQuery>; #[pallet::storage] pub(super) type FinalizedBeaconHeadersBlockRoot = @@ -173,13 +152,13 @@ pub mod pallet { #[pallet::storage] pub(super) type ExecutionHeaders = - StorageMap<_, Identity, H256, ExecutionHeader, OptionQuery>; + StorageMap<_, Identity, H256, CompactExecutionHeader, OptionQuery>; /// Current sync committee corresponding to the active header. /// TODO prune older sync committees than xxx #[pallet::storage] pub(super) type SyncCommittees = - StorageMap<_, Identity, u64, SyncCommitteeOf, ValueQuery>; + StorageMap<_, Identity, u64, SyncCommittee, OptionQuery>; #[pallet::storage] pub(super) type ValidatorsRoot = StorageValue<_, H256, ValueQuery>; @@ -199,24 +178,24 @@ pub mod pallet { pub(super) type Blocked = StorageValue<_, bool, ValueQuery>; #[pallet::genesis_config] - pub struct GenesisConfig { - pub initial_sync: Option>, + pub struct GenesisConfig { + pub initial_sync: Option, } #[cfg(feature = "std")] - impl Default for GenesisConfig { + impl Default for GenesisConfig { fn default() -> Self { GenesisConfig { initial_sync: None } } } #[pallet::genesis_build] - impl GenesisBuild for GenesisConfig { + impl GenesisBuild for GenesisConfig { fn build(&self) { log::info!( target: "ethereum-beacon-client", "💫 Sync committee size is: {}", - config::SYNC_COMMITTEE_SIZE + SYNC_COMMITTEE_SIZE ); if let Some(initial_sync) = self.initial_sync.clone() { @@ -232,22 +211,20 @@ pub mod pallet { #[transactional] pub fn sync_committee_period_update( origin: OriginFor, - sync_committee_period_update: SyncCommitteePeriodUpdateOf, + update: SyncCommitteeUpdate, ) -> DispatchResult { let _sender = ensure_signed(origin)?; Self::check_bridge_blocked_state()?; - let sync_committee_period = sync_committee_period_update.sync_committee_period; + let sync_committee_period = update.sync_committee_period; log::info!( target: "ethereum-beacon-client", "💫 Received sync committee update for period {}. Applying update", sync_committee_period ); - if let Err(err) = - Self::process_sync_committee_period_update(sync_committee_period_update) - { + if let Err(err) = Self::process_sync_committee_period_update(&update) { log::error!( target: "ethereum-beacon-client", "💫 Sync committee period update failed with error {:?}", @@ -270,7 +247,7 @@ pub mod pallet { #[transactional] pub fn import_finalized_header( origin: OriginFor, - finalized_header_update: FinalizedHeaderUpdateOf, + finalized_header_update: FinalizedHeaderUpdate, ) -> DispatchResult { let _sender = ensure_signed(origin)?; @@ -307,7 +284,7 @@ pub mod pallet { #[transactional] pub fn import_execution_header( origin: OriginFor, - update: HeaderUpdateOf, + update: HeaderUpdate, ) -> DispatchResult { let _sender = ensure_signed(origin)?; @@ -345,7 +322,7 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::unblock_bridge())] #[transactional] pub fn unblock_bridge(origin: OriginFor) -> DispatchResult { - let _sender = ensure_root(origin)?; + ensure_root(origin)?; >::set(false); @@ -356,69 +333,64 @@ pub mod pallet { } impl Pallet { - fn process_initial_sync(initial_sync: InitialSyncOf) -> DispatchResult { + fn process_initial_sync(update: &InitialUpdate) -> DispatchResult { Self::verify_sync_committee( - initial_sync.current_sync_committee.clone(), - initial_sync.current_sync_committee_branch, - initial_sync.header.state_root, - config::CURRENT_SYNC_COMMITTEE_DEPTH, + &update.current_sync_committee, + &update.current_sync_committee_branch, + update.header.state_root, config::CURRENT_SYNC_COMMITTEE_INDEX, )?; - let period = Self::compute_current_sync_period(initial_sync.header.slot); + let period = Self::compute_current_sync_period(update.header.slot); - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(initial_sync.header.clone()) - .map_err(|_| Error::::HeaderHashTreeRootFailed)? - .into(); + let block_root: H256 = update + .header + .hash_tree_root() + .map_err(|_| Error::::HeaderHashTreeRootFailed)?; - Self::store_sync_committee(period, initial_sync.current_sync_committee); - Self::store_validators_root(initial_sync.validators_root); + Self::store_sync_committee(period, &update.current_sync_committee); + Self::store_validators_root(update.validators_root); - let slot = initial_sync.header.slot; + let slot = update.header.slot; let last_finalized_header = FinalizedHeaderState { beacon_block_root: block_root, beacon_slot: slot, - import_time: initial_sync.import_time, + import_time: update.import_time, }; - >::insert(block_root, initial_sync.header); + >::insert(block_root, update.header.clone()); Self::add_finalized_header_slot(slot)?; >::set(last_finalized_header); Ok(()) } - fn process_sync_committee_period_update( - update: SyncCommitteePeriodUpdateOf, - ) -> DispatchResult { + fn process_sync_committee_period_update(update: &SyncCommitteeUpdate) -> DispatchResult { ensure!( update.signature_slot > update.attested_header.slot && update.attested_header.slot >= update.finalized_header.slot, Error::::InvalidSyncCommitteeHeaderUpdate ); - let sync_committee_bits = - get_sync_committee_bits(update.sync_aggregate.sync_committee_bits.clone()) - .map_err(|_| Error::::InvalidSyncCommitteeBits)?; - Self::sync_committee_participation_is_supermajority(sync_committee_bits.clone())?; + let participation = + decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits); + Self::sync_committee_participation_is_supermajority(&participation)?; Self::verify_sync_committee( - update.next_sync_committee.clone(), - update.next_sync_committee_branch, + &update.next_sync_committee, + &update.next_sync_committee_branch, update.attested_header.state_root, - config::NEXT_SYNC_COMMITTEE_DEPTH, config::NEXT_SYNC_COMMITTEE_INDEX, )?; - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .map_err(|_| Error::::HeaderHashTreeRootFailed)? - .into(); + let block_root: H256 = update + .finalized_header + .hash_tree_root() + .map_err(|_| Error::::HeaderHashTreeRootFailed)?; + Self::verify_header( block_root, - update.finality_branch, + &update.finality_branch, update.attested_header.state_root, - config::FINALIZED_ROOT_DEPTH, config::FINALIZED_ROOT_INDEX, )?; @@ -432,51 +404,47 @@ pub mod pallet { current_period, signature_slot_period ); - ensure!( - >::contains_key(current_period), - Error::::SyncCommitteeMissing - ); + + let current_sync_committee = + >::get(current_period).ok_or(Error::::SyncCommitteeMissing)?; let next_period = current_period + 1; ensure!( !>::contains_key(next_period), - Error::::InvalidSyncCommitteePeriodUpdateWithDuplication + Error::::InvalidSyncCommitteeUpdateWithDuplication ); ensure!( (next_period == latest_committee_period + 1), - Error::::InvalidSyncCommitteePeriodUpdateWithGap + Error::::InvalidSyncCommitteeUpdateWithGap ); - let current_sync_committee = Self::get_sync_committee_for_period(current_period)?; let validators_root = >::get(); - Self::verify_signed_header( - sync_committee_bits, - update.sync_aggregate.sync_committee_signature, - current_sync_committee.pubkeys, - update.attested_header, + &participation, + &update.sync_aggregate.sync_committee_signature, + ¤t_sync_committee.pubkeys, + update.attested_header.clone(), validators_root, update.signature_slot, )?; - ensure!( - Self::is_valid_merkle_branch( - update.block_roots_root, - update.block_roots_branch, - config::BLOCK_ROOTS_INDEX, - config::BLOCK_ROOTS_DEPTH, - update.finalized_header.state_root - ), + update.block_roots_branch.len() as u64 == config::BLOCK_ROOTS_DEPTH && + verify_merkle_proof( + update.block_roots_root, + &update.block_roots_branch, + config::BLOCK_ROOTS_INDEX, + update.finalized_header.state_root + ), Error::::InvalidAncestryMerkleProof ); Self::store_block_root(update.block_roots_root, block_root); - Self::store_sync_committee(next_period, update.next_sync_committee); - Self::store_finalized_header(block_root, update.finalized_header)?; + Self::store_sync_committee(next_period, &update.next_sync_committee); + Self::store_finalized_header(block_root, update.finalized_header.clone())?; Ok(()) } - fn process_finalized_header(update: FinalizedHeaderUpdateOf) -> DispatchResult { + fn process_finalized_header(update: FinalizedHeaderUpdate) -> DispatchResult { let last_finalized_header = >::get(); ensure!( update.signature_slot > update.attested_header.slot, @@ -493,7 +461,7 @@ pub mod pallet { let import_time = last_finalized_header.import_time; let weak_subjectivity_period_check = - import_time + T::WeakSubjectivityPeriodSeconds::get() as u64; + import_time + T::WeakSubjectivityPeriodSeconds::get(); let time: u64 = T::TimeProvider::now().as_secs(); log::info!( @@ -509,20 +477,19 @@ pub mod pallet { return Err(Error::::BridgeBlocked.into()) } - let sync_committee_bits = - get_sync_committee_bits(update.sync_aggregate.sync_committee_bits.clone()) - .map_err(|_| Error::::InvalidSyncCommitteeBits)?; - Self::sync_committee_participation_is_supermajority(sync_committee_bits.clone())?; + let participation = + decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits); + Self::sync_committee_participation_is_supermajority(&participation)?; + + let block_root: H256 = update + .finalized_header + .hash_tree_root() + .map_err(|_| Error::::HeaderHashTreeRootFailed)?; - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .map_err(|_| Error::::HeaderHashTreeRootFailed)? - .into(); Self::verify_header( block_root, - update.finality_branch, + &update.finality_branch, update.attested_header.state_root, - config::FINALIZED_ROOT_DEPTH, config::FINALIZED_ROOT_INDEX, )?; @@ -534,26 +501,28 @@ pub mod pallet { current_period == last_finalized_period + 1), Error::::InvalidFinalizedPeriodUpdate ); - let sync_committee = Self::get_sync_committee_for_period(current_period)?; + + let sync_committee = + >::get(current_period).ok_or(Error::::SyncCommitteeMissing)?; let validators_root = >::get(); Self::verify_signed_header( - sync_committee_bits, - update.sync_aggregate.sync_committee_signature, - sync_committee.pubkeys, + &participation, + &update.sync_aggregate.sync_committee_signature, + &sync_committee.pubkeys, update.attested_header, validators_root, update.signature_slot, )?; ensure!( - Self::is_valid_merkle_branch( - update.block_roots_root, - update.block_roots_branch, - config::BLOCK_ROOTS_INDEX, - config::BLOCK_ROOTS_DEPTH, - update.finalized_header.state_root - ), + update.block_roots_branch.len() as u64 == config::BLOCK_ROOTS_DEPTH && + verify_merkle_proof( + update.block_roots_root, + &update.block_roots_branch, + config::BLOCK_ROOTS_INDEX, + update.finalized_header.state_root + ), Error::::InvalidAncestryMerkleProof ); @@ -571,44 +540,38 @@ pub mod pallet { ); } - fn process_header(update: HeaderUpdateOf) -> DispatchResult { + fn process_header(update: HeaderUpdate) -> DispatchResult { let last_finalized_header = >::get(); let latest_finalized_header_slot = last_finalized_header.beacon_slot; let block_slot = update.beacon_header.slot; ensure!(block_slot <= latest_finalized_header_slot, Error::::HeaderNotFinalized); let execution_header_state = >::get(); - - let execution_header: ExecutionHeader = update - .execution_header - .clone() - .try_into() - .map_err(|_| Error::::ExecutionHeaderMappingFailed)?; ensure!( - execution_header.block_number > execution_header_state.block_number, + update.execution_header.block_number > execution_header_state.block_number, Error::::InvalidExecutionHeaderUpdate ); - let execution_root = - merkleization::hash_tree_root_execution_header(update.execution_header.clone()) - .map_err(|_| Error::::BlockBodyHashTreeRootFailed)?; - let execution_root_hash: H256 = execution_root.into(); + let execution_root: H256 = update + .execution_header + .hash_tree_root() + .map_err(|_| Error::::BlockBodyHashTreeRootFailed)?; ensure!( - Self::is_valid_merkle_branch( - execution_root_hash, - update.execution_branch, - config::EXECUTION_HEADER_DEPTH, - config::EXECUTION_HEADER_INDEX, - update.beacon_header.body_root - ), + update.execution_branch.len() as u64 == config::EXECUTION_HEADER_DEPTH && + verify_merkle_proof( + execution_root, + &update.execution_branch, + config::EXECUTION_HEADER_INDEX, + update.beacon_header.body_root + ), Error::::InvalidExecutionHeaderProof ); - let beacon_block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.beacon_header.clone()) - .map_err(|_| Error::::HeaderHashTreeRootFailed)? - .into(); + let beacon_block_root: H256 = update + .beacon_header + .hash_tree_root() + .map_err(|_| Error::::HeaderHashTreeRootFailed)?; Self::ancestry_proof( update.block_root_branch, @@ -618,27 +581,25 @@ pub mod pallet { )?; let current_period = Self::compute_current_sync_period(update.beacon_header.slot); - let sync_committee = Self::get_sync_committee_for_period(current_period)?; + let sync_committee = + >::get(current_period).ok_or(Error::::SyncCommitteeMissing)?; let validators_root = >::get(); - let sync_committee_bits = - get_sync_committee_bits(update.sync_aggregate.sync_committee_bits.clone()) - .map_err(|_| Error::::InvalidSyncCommitteeBits)?; + let participation = + decompress_sync_committee_bits(update.sync_aggregate.sync_committee_bits); Self::verify_signed_header( - sync_committee_bits, - update.sync_aggregate.sync_committee_signature, - sync_committee.pubkeys, + &participation, + &update.sync_aggregate.sync_committee_signature, + &sync_committee.pubkeys, update.beacon_header, validators_root, update.signature_slot, )?; - let block_hash = execution_header.block_hash; - Self::store_execution_header( - block_hash, - execution_header, + update.execution_header.block_hash, + update.execution_header.into(), block_slot, beacon_block_root, ); @@ -647,7 +608,7 @@ pub mod pallet { } fn ancestry_proof( - block_root_proof: BoundedVec, + block_root_proof: Vec, block_slot: u64, beacon_block_root: H256, finalized_header_root: H256, @@ -655,7 +616,7 @@ pub mod pallet { // If the block root proof is empty, we know that we expect this header to be a // finalized header. We need to check that the header hash matches the finalized header // root at the expected slot. - if block_root_proof.len() == 0 { + if block_root_proof.is_empty() { let stored_finalized_header = >::get(beacon_block_root); if stored_finalized_header.is_none() { log::error!( @@ -688,9 +649,8 @@ pub mod pallet { return Err(Error::::ExpectedFinalizedHeaderNotStored.into()) } - let max_slots_per_historical_root = T::MaxSlotsPerHistoricalRoot::get(); - let index_in_array = block_slot % max_slots_per_historical_root; - let leaf_index = max_slots_per_historical_root + index_in_array; + let index_in_array = block_slot % (SLOTS_PER_HISTORICAL_ROOT as u64); + let leaf_index = (SLOTS_PER_HISTORICAL_ROOT as u64) + index_in_array; log::info!( target: "ethereum-beacon-client", @@ -698,13 +658,13 @@ pub mod pallet { ); ensure!( - Self::is_valid_merkle_branch( - beacon_block_root, - block_root_proof, - config::BLOCK_ROOT_AT_INDEX_PROOF_DEPTH, - leaf_index, - finalized_block_root_hash - ), + block_root_proof.len() as u64 == config::BLOCK_ROOT_AT_INDEX_PROOF_DEPTH && + verify_merkle_proof( + beacon_block_root, + &block_root_proof, + leaf_index, + finalized_block_root_hash + ), Error::::InvalidAncestryMerkleProof ); @@ -720,9 +680,9 @@ pub mod pallet { } pub(super) fn verify_signed_header( - sync_committee_bits: Vec, - sync_committee_signature: BoundedVec, - sync_committee_pubkeys: BoundedVec, + sync_committee_bits: &[u8], + sync_committee_signature: &Signature, + sync_committee_pubkeys: &[PublicKey], header: BeaconHeader, validators_root: H256, signature_slot: u64, @@ -731,9 +691,8 @@ pub mod pallet { // Gathers all the pubkeys of the sync committee members that participated in signing // the header. for (bit, pubkey) in sync_committee_bits.iter().zip(sync_committee_pubkeys.iter()) { - if *bit == 1 as u8 { - let pubk = pubkey.clone(); - participant_pubkeys.push(pubk); + if *bit == 1_u8 { + participant_pubkeys.push(*pubkey); } } @@ -749,7 +708,7 @@ pub mod pallet { // Verify sync committee aggregate signature. Self::bls_fast_aggregate_verify( - participant_pubkeys, + &participant_pubkeys, signing_root, sync_committee_signature, )?; @@ -758,15 +717,15 @@ pub mod pallet { } pub(super) fn compute_epoch_at_slot(signature_slot: u64, slots_per_epoch: u64) -> u64 { - return signature_slot / slots_per_epoch + signature_slot / slots_per_epoch } pub(super) fn bls_fast_aggregate_verify( - pubkeys: Vec, + pubkeys: &[PublicKey], message: H256, - signature: BoundedVec, + signature: &Signature, ) -> DispatchResult { - let sig = Signature::from_bytes(&signature[..]); + let sig = milagro_bls::Signature::from_bytes(&signature.0[..]); if let Err(_e) = sig { return Err(Error::::InvalidSignature.into()) } @@ -792,7 +751,7 @@ pub mod pallet { ensure!( agg_sig.fast_aggregate_verify_pre_aggregated( - &message.as_bytes(), + message.as_bytes(), &agg_pub_key_res.unwrap() ), Error::::SignatureVerificationFailed @@ -803,40 +762,37 @@ pub mod pallet { pub(super) fn compute_signing_root( beacon_header: BeaconHeader, - domain: Domain, - ) -> Result { - let beacon_header_root = merkleization::hash_tree_root_beacon_header(beacon_header) + domain: H256, + ) -> Result { + let beacon_header_root = beacon_header + .hash_tree_root() .map_err(|_| Error::::HeaderHashTreeRootFailed)?; - let header_hash_tree_root: H256 = beacon_header_root.into(); - - let hash_root = merkleization::hash_tree_root_signing_data(SigningData { - object_root: header_hash_tree_root, - domain, - }) - .map_err(|_| Error::::SigningRootHashTreeRootFailed)?; + let hash_root = SigningData { object_root: beacon_header_root, domain } + .hash_tree_root() + .map_err(|_| Error::::SigningRootHashTreeRootFailed)?; - Ok(hash_root.into()) + Ok(hash_root) } fn verify_sync_committee( - sync_committee: SyncCommitteeOf, - sync_committee_branch: BoundedVec, + sync_committee: &SyncCommittee, + sync_committee_branch: &[H256], header_state_root: H256, - depth: u64, index: u64, ) -> DispatchResult { - let sync_committee_root = merkleization::hash_tree_root_sync_committee(sync_committee) + let sync_committee_root = sync_committee + .hash_tree_root() .map_err(|_| Error::::SyncCommitteeHashTreeRootFailed)?; ensure!( - Self::is_valid_merkle_branch( - sync_committee_root.into(), - sync_committee_branch, - depth, - index, - header_state_root - ), + sync_committee_branch.len() as u64 == config::SYNC_COMMITTEE_DEPTH && + verify_merkle_proof( + sync_committee_root, + sync_committee_branch, + index, + header_state_root + ), Error::::InvalidSyncCommitteeMerkleProof ); @@ -845,26 +801,24 @@ pub mod pallet { fn verify_header( block_root: H256, - proof_branch: BoundedVec, + proof_branch: &[H256], attested_header_state_root: H256, - depth: u64, index: u64, ) -> DispatchResult { ensure!( - Self::is_valid_merkle_branch( - block_root, - proof_branch, - depth, - index, - attested_header_state_root - ), + proof_branch.len() as u64 == config::FINALIZED_ROOT_DEPTH && + verify_merkle_proof( + block_root, + proof_branch, + index, + attested_header_state_root + ), Error::::InvalidHeaderMerkleProof ); - Ok(()) } - fn store_sync_committee(period: u64, sync_committee: SyncCommitteeOf) { + fn store_sync_committee(period: u64, sync_committee: &SyncCommittee) { >::insert(period, sync_committee); log::trace!( @@ -878,7 +832,7 @@ pub mod pallet { Self::deposit_event(Event::SyncCommitteeUpdated { period }); } - fn store_finalized_header(block_root: Root, header: BeaconHeader) -> DispatchResult { + fn store_finalized_header(block_root: H256, header: BeaconHeader) -> DispatchResult { let slot = header.slot; >::insert(block_root, header); @@ -904,7 +858,7 @@ pub mod pallet { fn add_finalized_header_slot(slot: u64) -> DispatchResult { >::try_mutate(|b_vec| { - if b_vec.len() as u32 == T::MaxFinalizedHeaderSlotArray::get() { + if b_vec.len() as u32 == MAX_FINALIZED_HEADER_SLOT_ARRAY { b_vec.remove(0); } b_vec.try_push(slot) @@ -916,29 +870,30 @@ pub mod pallet { fn store_execution_header( block_hash: H256, - header: ExecutionHeader, + header: CompactExecutionHeader, beacon_slot: u64, beacon_block_root: H256, ) { - let block_number = header.block_number; - - >::insert(block_hash, header); + >::insert(block_hash, header.clone()); log::trace!( target: "ethereum-beacon-client", "💫 Updated latest execution block at {} to number {}.", block_hash, - block_number + header.block_number ); LatestExecutionHeaderState::::mutate(|s| { s.beacon_block_root = beacon_block_root; s.beacon_slot = beacon_slot; s.block_hash = block_hash; - s.block_number = block_number; + s.block_number = header.block_number; }); - Self::deposit_event(Event::ExecutionHeaderImported { block_hash, block_number }); + Self::deposit_event(Event::ExecutionHeaderImported { + block_hash, + block_number: header.block_number, + }); } fn store_validators_root(validators_root: H256) { @@ -951,7 +906,7 @@ pub mod pallet { /// /// let sync_committee_bits = vec![0, 1, 0, 1, 1, 1]; /// ensure!(get_sync_committee_sum(sync_committee_bits), 4); - pub(super) fn get_sync_committee_sum(sync_committee_bits: Vec) -> u64 { + pub(super) fn get_sync_committee_sum(sync_committee_bits: &[u8]) -> u64 { sync_committee_bits.iter().fold(0, |acc: u64, x| acc + *x as u64) } @@ -963,8 +918,8 @@ pub mod pallet { pub(super) fn compute_domain( domain_type: Vec, fork_version: ForkVersion, - genesis_validators_root: Root, - ) -> Result { + genesis_validators_root: H256, + ) -> Result { let fork_data_root = Self::compute_fork_data_root(fork_version, genesis_validators_root)?; @@ -977,83 +932,30 @@ pub mod pallet { fn compute_fork_data_root( current_version: ForkVersion, - genesis_validators_root: Root, - ) -> Result { - let hash_root = merkleization::hash_tree_root_fork_data(ForkData { + genesis_validators_root: H256, + ) -> Result { + let hash_root = ForkData { current_version, genesis_validators_root: genesis_validators_root.into(), - }) - .map_err(|_| Error::::ForkDataHashTreeRootFailed)?; - - Ok(hash_root.into()) - } - - pub(super) fn is_valid_merkle_branch( - leaf: H256, - branch: BoundedVec, - depth: u64, - index: u64, - root: Root, - ) -> bool { - if branch.len() as u64 != depth { - log::error!(target: "ethereum-beacon-client", "Merkle proof branch length doesn't match depth."); - - return false - } - let mut value = leaf; - if leaf.as_bytes().len() < 32 as usize { - log::error!(target: "ethereum-beacon-client", "Merkle proof leaf not 32 bytes."); - - return false - } - for i in 0..depth { - if branch[i as usize].as_bytes().len() < 32 as usize { - log::error!(target: "ethereum-beacon-client", "Merkle proof branch not 32 bytes."); - - return false - } - if (index / (2u32.pow(i as u32) as u64) % 2) == 0 { - // left node - let mut data = [0u8; 64]; - data[0..32].copy_from_slice(&(value.0)); - data[32..64].copy_from_slice(&(branch[i as usize].0)); - value = sha2_256(&data).into(); - } else { - let mut data = [0u8; 64]; // right node - data[0..32].copy_from_slice(&(branch[i as usize].0)); - data[32..64].copy_from_slice(&(value.0)); - value = sha2_256(&data).into(); - } } + .hash_tree_root() + .map_err(|_| Error::::ForkDataHashTreeRootFailed)?; - return value == root + Ok(hash_root) } pub(super) fn sync_committee_participation_is_supermajority( - sync_committee_bits: Vec, + sync_committee_bits: &[u8], ) -> DispatchResult { - let sync_committee_sum = Self::get_sync_committee_sum(sync_committee_bits.clone()); + let sync_committee_sum = Self::get_sync_committee_sum(sync_committee_bits); ensure!( - (sync_committee_sum * 3 >= sync_committee_bits.clone().len() as u64 * 2), + (sync_committee_sum * 3 >= sync_committee_bits.len() as u64 * 2), Error::::SyncCommitteeParticipantsNotSupermajority ); Ok(()) } - pub(super) fn get_sync_committee_for_period( - period: u64, - ) -> Result, DispatchError> { - let sync_committee = >::get(period); - - if sync_committee.pubkeys.len() == 0 { - log::error!(target: "ethereum-beacon-client", "💫 Sync committee for period {} missing", period); - return Err(Error::::SyncCommitteeMissing.into()) - } - - Ok(sync_committee) - } - pub(super) fn compute_fork_version(epoch: u64) -> ForkVersion { let fork_versions = T::ForkVersions::get(); @@ -1067,16 +969,16 @@ pub mod pallet { return fork_versions.altair.version } - return fork_versions.genesis.version + fork_versions.genesis.version } - pub(super) fn initial_sync(initial_sync: InitialSyncOf) -> Result<(), &'static str> { + pub(super) fn initial_sync(update: InitialUpdate) -> Result<(), &'static str> { log::info!( target: "ethereum-beacon-client", "💫 Received initial sync, starting processing.", ); - if let Err(err) = Self::process_initial_sync(initial_sync) { + if let Err(err) = Self::process_initial_sync(&update) { log::error!( target: "ethereum-beacon-client", "Initial sync failed with error {:?}", @@ -1097,11 +999,10 @@ pub mod pallet { // in the block given by proof.block_hash. Inclusion is only // recognized if the block has been finalized. fn verify_receipt_inclusion( - stored_header: ExecutionHeader, + receipts_root: H256, proof: &Proof, ) -> Result { - let result = stored_header - .check_receipt_proof(&proof.data.1) + let result = verify_receipt_proof(receipts_root, &proof.data.1) .ok_or(Error::::InvalidProof)?; match result { @@ -1128,10 +1029,11 @@ pub mod pallet { message.proof.block_hash, ); - let stored_header = >::get(message.proof.block_hash) + let header = >::get(message.proof.block_hash) .ok_or(Error::::MissingHeader)?; - let receipt = match Self::verify_receipt_inclusion(stored_header, &message.proof) { + let receipt = match Self::verify_receipt_inclusion(header.receipts_root, &message.proof) + { Ok(receipt) => receipt, Err(err) => { log::error!( diff --git a/parachain/pallets/ethereum-beacon-client/src/merkleization.rs b/parachain/pallets/ethereum-beacon-client/src/merkleization.rs deleted file mode 100644 index 6a80b7890..000000000 --- a/parachain/pallets/ethereum-beacon-client/src/merkleization.rs +++ /dev/null @@ -1,197 +0,0 @@ -use core::array::TryFromSliceError; - -use crate::{config, ssz::*}; -use byte_slice_cast::AsByteSlice; -use frame_support::{traits::Get, BoundedVec}; -use snowbridge_beacon_primitives::{ - BeaconHeader, ExecutionPayloadHeader, ForkData, SigningData, SyncAggregate, SyncCommittee, -}; -use sp_std::{convert::TryInto, iter::FromIterator, prelude::*}; -use ssz_rs::{ - prelude::{List, Vector}, - Bitvector, Deserialize, DeserializeError, SimpleSerialize as SimpleSerializeTrait, U256, -}; - -#[derive(Debug, PartialEq)] -pub enum MerkleizationError { - HashTreeRootError, - HashTreeRootInvalidBytes, - InvalidLength, - ExpectedFurtherInput { provided: u64, expected: u64 }, - AdditionalInput { provided: u64, expected: u64 }, - InvalidInput, - DeserializeError, - ListError, -} - -impl From for MerkleizationError { - fn from(_: TryFromSliceError) -> Self { - return MerkleizationError::InvalidLength - } -} - -impl From for MerkleizationError { - fn from(_: DeserializeError) -> Self { - return MerkleizationError::DeserializeError - } -} - -impl, LogsBloomSize: Get, ExtraDataSize: Get> - TryFrom> - for SSZExecutionPayloadHeader -{ - type Error = MerkleizationError; - - fn try_from( - execution_payload: ExecutionPayloadHeader, - ) -> Result { - Ok(SSZExecutionPayloadHeader { - parent_hash: execution_payload.parent_hash.as_bytes().try_into()?, - fee_recipient: Vector::::from_iter(execution_payload.fee_recipient), - state_root: execution_payload.state_root.as_bytes().try_into()?, - receipts_root: execution_payload.receipts_root.as_bytes().try_into()?, - logs_bloom: Vector::::from_iter(execution_payload.logs_bloom), - prev_randao: execution_payload.prev_randao.as_bytes().try_into()?, - block_number: execution_payload.block_number, - gas_limit: execution_payload.gas_limit, - gas_used: execution_payload.gas_used, - timestamp: execution_payload.timestamp, - extra_data: List::::try_from( - execution_payload.extra_data.into_inner(), - ) - .map_err(|_| MerkleizationError::ListError)?, - base_fee_per_gas: U256::try_from_bytes_le( - &(execution_payload.base_fee_per_gas.as_byte_slice()), - )?, - block_hash: execution_payload.block_hash.as_bytes().try_into()?, - transactions_root: execution_payload.transactions_root.as_bytes().try_into()?, - withdrawals_root: execution_payload.withdrawals_root.as_bytes().try_into()?, - }) - } -} - -impl TryFrom for SSZBeaconBlockHeader { - type Error = MerkleizationError; - - fn try_from(beacon_header: BeaconHeader) -> Result { - Ok(SSZBeaconBlockHeader { - slot: beacon_header.slot, - proposer_index: beacon_header.proposer_index, - parent_root: beacon_header.parent_root.as_bytes().try_into()?, - state_root: beacon_header.state_root.as_bytes().try_into()?, - body_root: beacon_header.body_root.as_bytes().try_into()?, - }) - } -} - -impl, SignatureSize: Get> - TryFrom> for SSZSyncAggregate -{ - type Error = MerkleizationError; - - fn try_from( - sync_aggregate: SyncAggregate, - ) -> Result { - Ok(SSZSyncAggregate { - sync_committee_bits: Bitvector::<{ config::SYNC_COMMITTEE_SIZE }>::deserialize( - &sync_aggregate.sync_committee_bits, - )?, - sync_committee_signature: Vector::::from_iter( - sync_aggregate.sync_committee_signature, - ), - }) - } -} - -pub fn hash_tree_root_beacon_header( - beacon_header: BeaconHeader, -) -> Result<[u8; 32], MerkleizationError> { - let ssz_beacon_header: SSZBeaconBlockHeader = beacon_header.try_into()?; - - hash_tree_root(ssz_beacon_header) -} - -pub fn hash_tree_root_execution_header< - FeeRecipientSize: Get, - LogsBloomSize: Get, - ExtraDataSize: Get, ->( - execution_header: ExecutionPayloadHeader, -) -> Result<[u8; 32], MerkleizationError> { - let ssz_execution_payload: SSZExecutionPayloadHeader = execution_header.try_into()?; - hash_tree_root(ssz_execution_payload) -} - -pub fn hash_tree_root_sync_committee>( - sync_committee: SyncCommittee, -) -> Result<[u8; 32], MerkleizationError> { - let mut pubkeys_vec = Vec::new(); - - for pubkey in sync_committee.pubkeys.iter() { - let conv_pubkey = Vector::::from_iter(pubkey.0); - - pubkeys_vec.push(conv_pubkey); - } - - let pubkeys = - Vector::, { config::SYNC_COMMITTEE_SIZE }>::from_iter(pubkeys_vec.clone()); - - let agg = Vector::::from_iter(sync_committee.aggregate_pubkey.0); - - hash_tree_root(SSZSyncCommittee { pubkeys, aggregate_pubkey: agg }) -} - -pub fn hash_tree_root_fork_data(fork_data: ForkData) -> Result<[u8; 32], MerkleizationError> { - hash_tree_root(SSZForkData { - current_version: fork_data.current_version, - genesis_validators_root: fork_data.genesis_validators_root, - }) -} - -pub fn hash_tree_root_signing_data( - signing_data: SigningData, -) -> Result<[u8; 32], MerkleizationError> { - hash_tree_root(SSZSigningData { - object_root: signing_data.object_root.into(), - domain: signing_data.domain.into(), - }) -} - -pub fn hash_tree_root( - mut object: T, -) -> Result<[u8; 32], MerkleizationError> { - match object.hash_tree_root() { - Ok(node) => node - .as_bytes() - .try_into() - .map_err(|_| MerkleizationError::HashTreeRootInvalidBytes), - Err(_e) => Err(MerkleizationError::HashTreeRootError), - } -} - -pub fn get_sync_committee_bits>( - bits_hex: BoundedVec, -) -> Result, MerkleizationError> { - let bitv = Bitvector::<{ config::SYNC_COMMITTEE_SIZE }>::deserialize(&bits_hex).map_err( - //|_| MerkleizationError::InvalidInput - |e| -> MerkleizationError { - match e { - DeserializeError::ExpectedFurtherInput { provided, expected } => - MerkleizationError::ExpectedFurtherInput { - provided: provided as u64, - expected: expected as u64, - }, - DeserializeError::AdditionalInput { provided, expected } => - MerkleizationError::AdditionalInput { - provided: provided as u64, - expected: expected as u64, - }, - _ => MerkleizationError::InvalidInput, - } - }, - )?; - - let result = bitv.iter().map(|bit| if bit == true { 1 } else { 0 }).collect::>(); - - Ok(result) -} diff --git a/parachain/pallets/ethereum-beacon-client/src/mock.rs b/parachain/pallets/ethereum-beacon-client/src/mock.rs index ff2bc9638..bb83a5a2e 100644 --- a/parachain/pallets/ethereum-beacon-client/src/mock.rs +++ b/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -1,9 +1,12 @@ -use super::*; +//use super::*; + +use crate::config; + use crate as ethereum_beacon_client; use frame_support::parameter_types; use frame_system as system; use pallet_timestamp; -use snowbridge_beacon_primitives::{BeaconHeader, Fork, ForkVersions}; +use primitives::{BeaconHeader, Fork, ForkVersions, PublicKey, Signature}; use sp_core::H256; use sp_runtime::{ testing::Header, @@ -25,7 +28,7 @@ pub mod mock_minimal { { System: frame_system::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Config, Storage, Event}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Config, Storage, Event}, } ); @@ -69,15 +72,6 @@ pub mod mock_minimal { } parameter_types! { - pub const MaxSyncCommitteeSize: u32 = config::SYNC_COMMITTEE_SIZE as u32; - pub const MaxProofBranchSize: u32 = 20; - pub const MaxExtraDataSize: u32 = config::MAX_EXTRA_DATA_BYTES as u32; - pub const MaxLogsBloomSize: u32 = config::MAX_LOGS_BLOOM_SIZE as u32; - pub const MaxFeeRecipientSize: u32 = config::MAX_FEE_RECIPIENT_SIZE as u32; - pub const MaxPublicKeySize: u32 = config::PUBKEY_SIZE as u32; - pub const MaxSignatureSize: u32 = config::SIGNATURE_SIZE as u32; - pub const MaxSlotsPerHistoricalRoot: u64 = 64; - pub const MaxFinalizedHeaderSlotArray: u32 = 1000; pub const WeakSubjectivityPeriodSeconds: u32 = 97200; pub const ChainForkVersions: ForkVersions = ForkVersions{ genesis: Fork { @@ -102,15 +96,6 @@ pub mod mock_minimal { impl ethereum_beacon_client::Config for Test { type TimeProvider = pallet_timestamp::Pallet; type RuntimeEvent = RuntimeEvent; - type MaxSyncCommitteeSize = MaxSyncCommitteeSize; - type MaxProofBranchSize = MaxProofBranchSize; - type MaxExtraDataSize = MaxExtraDataSize; - type MaxLogsBloomSize = MaxLogsBloomSize; - type MaxFeeRecipientSize = MaxFeeRecipientSize; - type MaxPublicKeySize = MaxPublicKeySize; - type MaxSignatureSize = MaxSignatureSize; - type MaxSlotsPerHistoricalRoot = MaxSlotsPerHistoricalRoot; - type MaxFinalizedHeaderSlotArray = MaxFinalizedHeaderSlotArray; type ForkVersions = ChainForkVersions; type WeakSubjectivityPeriodSeconds = WeakSubjectivityPeriodSeconds; type WeightInfo = (); @@ -131,7 +116,7 @@ pub mod mock_mainnet { { System: frame_system::{Pallet, Call, Storage, Event}, Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent}, - EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Config, Storage, Event}, + EthereumBeaconClient: ethereum_beacon_client::{Pallet, Call, Config, Storage, Event}, } ); @@ -175,15 +160,6 @@ pub mod mock_mainnet { } parameter_types! { - pub const MaxSyncCommitteeSize: u32 = config::SYNC_COMMITTEE_SIZE as u32; - pub const MaxProofBranchSize: u32 = 20; - pub const MaxExtraDataSize: u32 = config::MAX_EXTRA_DATA_BYTES as u32; - pub const MaxLogsBloomSize: u32 = config::MAX_LOGS_BLOOM_SIZE as u32; - pub const MaxFeeRecipientSize: u32 = config::MAX_FEE_RECIPIENT_SIZE as u32; - pub const MaxPublicKeySize: u32 = config::PUBKEY_SIZE as u32; - pub const MaxSignatureSize: u32 = config::SIGNATURE_SIZE as u32; - pub const MaxSlotsPerHistoricalRoot: u64 = 8192; - pub const MaxFinalizedHeaderSlotArray: u32 = 1000; pub const WeakSubjectivityPeriodSeconds: u32 = 97200; pub const ChainForkVersions: ForkVersions = ForkVersions{ genesis: Fork { @@ -208,15 +184,6 @@ pub mod mock_mainnet { impl ethereum_beacon_client::Config for Test { type RuntimeEvent = RuntimeEvent; type TimeProvider = pallet_timestamp::Pallet; - type MaxSyncCommitteeSize = MaxSyncCommitteeSize; - type MaxProofBranchSize = MaxProofBranchSize; - type MaxExtraDataSize = MaxExtraDataSize; - type MaxLogsBloomSize = MaxLogsBloomSize; - type MaxFeeRecipientSize = MaxFeeRecipientSize; - type MaxPublicKeySize = MaxPublicKeySize; - type MaxSignatureSize = MaxSignatureSize; - type MaxSlotsPerHistoricalRoot = MaxSlotsPerHistoricalRoot; - type MaxFinalizedHeaderSlotArray = MaxFinalizedHeaderSlotArray; type ForkVersions = ChainForkVersions; type WeakSubjectivityPeriodSeconds = WeakSubjectivityPeriodSeconds; type WeightInfo = (); @@ -228,10 +195,13 @@ pub fn new_tester() -> sp_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() } -pub struct BLSSignatureVerifyTest { - pub sync_committee_bits: Vec, - pub sync_committee_signature: Vec, - pub pubkeys: Vec, +pub struct BLSSignatureVerifyTest< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +> { + pub sync_committee_bits: [u8; SYNC_COMMITTEE_BITS_SIZE], + pub sync_committee_signature: Signature, + pub pubkeys: [PublicKey; SYNC_COMMITTEE_SIZE], pub header: BeaconHeader, pub validators_root: H256, pub signature_slot: u64, @@ -241,45 +211,46 @@ fn fixture_path(name: &str) -> PathBuf { [env!("CARGO_MANIFEST_DIR"), "tests", "fixtures", name].iter().collect() } -fn initial_sync_from_file( +fn initial_sync_from_file( name: &str, -) -> InitialSync { +) -> primitives::InitialUpdate { let filepath = fixture_path(name); serde_json::from_reader(File::open(&filepath).unwrap()).unwrap() } -fn sync_committee_update_from_file( +fn sync_committee_update_from_file< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>( name: &str, -) -> SyncCommitteePeriodUpdate -{ +) -> primitives::SyncCommitteeUpdate { let filepath = fixture_path(name); serde_json::from_reader(File::open(&filepath).unwrap()).unwrap() } -fn sync_committee_from_file( +fn sync_committee_from_file( name: &str, -) -> SyncCommittee { +) -> primitives::SyncCommittee { let filepath = fixture_path(name); serde_json::from_reader(File::open(&filepath).unwrap()).unwrap() } -fn finalized_header_update_from_file( +fn finalized_header_update_from_file< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>( name: &str, -) -> FinalizedHeaderUpdate { +) -> primitives::FinalizedHeaderUpdate { let filepath = fixture_path(name); serde_json::from_reader(File::open(&filepath).unwrap()).unwrap() } -fn header_update_from_file( +fn header_update_from_file< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>( name: &str, -) -> HeaderUpdate< - T::MaxFeeRecipientSize, - T::MaxLogsBloomSize, - T::MaxExtraDataSize, - T::MaxSignatureSize, - T::MaxProofBranchSize, - T::MaxSyncCommitteeSize, -> { +) -> primitives::HeaderUpdate { let filepath = fixture_path(name); serde_json::from_reader(File::open(&filepath).unwrap()).unwrap() } @@ -300,67 +271,62 @@ fn add_file_prefix(name: &str) -> String { result } -pub fn get_initial_sync( -) -> InitialSync { - initial_sync_from_file::(&add_file_prefix("initial_sync.json")) +pub fn get_initial_sync( +) -> primitives::InitialUpdate { + initial_sync_from_file::(&add_file_prefix("initial_sync.json")) } -pub fn get_committee_sync_period_update( -) -> SyncCommitteePeriodUpdate -{ - sync_committee_update_from_file::(&add_file_prefix("sync_committee_update.json")) +pub fn get_committee_sync_period_update< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>() -> primitives::SyncCommitteeUpdate { + sync_committee_update_from_file::( + &add_file_prefix("sync_committee_update.json"), + ) } -pub fn get_committee_sync_ssz_test_data() -> SyncCommittee -{ +pub fn get_committee_sync_ssz_test_data( +) -> primitives::SyncCommittee { let mut filename: String = "ssz_test_".to_owned(); filename.push_str(&get_config_setting()); filename.push_str("_sync_committee.json"); - sync_committee_from_file::(filename.as_str()) + sync_committee_from_file::(filename.as_str()) } -pub fn get_header_update() -> HeaderUpdate< - T::MaxFeeRecipientSize, - T::MaxLogsBloomSize, - T::MaxExtraDataSize, - T::MaxSignatureSize, - T::MaxProofBranchSize, - T::MaxSyncCommitteeSize, -> { - header_update_from_file::(&add_file_prefix("header_update.json")) +pub fn get_header_update< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>() -> primitives::HeaderUpdate { + header_update_from_file::(&add_file_prefix( + "header_update.json", + )) } -pub fn get_finalized_header_update( -) -> FinalizedHeaderUpdate { - finalized_header_update_from_file::(&add_file_prefix("finalized_header_update.json")) +pub fn get_finalized_header_update< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>() -> primitives::FinalizedHeaderUpdate { + finalized_header_update_from_file::( + &add_file_prefix("finalized_header_update.json"), + ) } -pub fn get_validators_root() -> H256 { - get_initial_sync::().validators_root +pub fn get_validators_root() -> H256 { + get_initial_sync::().validators_root } -pub fn get_bls_signature_verify_test_data() -> BLSSignatureVerifyTest { - let finalized_update = get_finalized_header_update::(); - let initial_sync = get_initial_sync::(); +pub fn get_bls_signature_verify_test_data< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>() -> BLSSignatureVerifyTest { + let finalized_update = + get_finalized_header_update::(); + let initial_sync = get_initial_sync::(); BLSSignatureVerifyTest { - sync_committee_bits: finalized_update - .sync_aggregate - .sync_committee_bits - .try_into() - .expect("sync committee bits are too long"), - sync_committee_signature: finalized_update - .sync_aggregate - .sync_committee_signature - .to_vec() - .try_into() - .expect("signature is too long"), - pubkeys: initial_sync - .current_sync_committee - .pubkeys - .to_vec() - .try_into() - .expect("pubkeys are too long"), + sync_committee_bits: finalized_update.sync_aggregate.sync_committee_bits, + sync_committee_signature: finalized_update.sync_aggregate.sync_committee_signature, + pubkeys: initial_sync.current_sync_committee.pubkeys, header: finalized_update.attested_header, validators_root: initial_sync.validators_root, signature_slot: finalized_update.signature_slot, diff --git a/parachain/pallets/ethereum-beacon-client/src/ssz.rs b/parachain/pallets/ethereum-beacon-client/src/ssz.rs deleted file mode 100644 index 4bb92e23e..000000000 --- a/parachain/pallets/ethereum-beacon-client/src/ssz.rs +++ /dev/null @@ -1,59 +0,0 @@ -use crate::config; -use sp_std::{vec, vec::Vec}; -use ssz_rs::{ - prelude::{List, Vector}, - Bitvector, Deserialize, Sized, U256, -}; -use ssz_rs_derive::SimpleSerialize; - -#[derive(Default, SimpleSerialize, Clone, Debug)] -pub struct SSZBeaconBlockHeader { - pub slot: u64, - pub proposer_index: u64, - pub parent_root: [u8; 32], - pub state_root: [u8; 32], - pub body_root: [u8; 32], -} - -#[derive(Default, SimpleSerialize)] -pub struct SSZSyncCommittee { - pub pubkeys: Vector, { config::SYNC_COMMITTEE_SIZE }>, - pub aggregate_pubkey: Vector, -} - -#[derive(Default, Debug, SimpleSerialize, Clone)] -pub struct SSZSyncAggregate { - pub sync_committee_bits: Bitvector<{ config::SYNC_COMMITTEE_SIZE }>, - pub sync_committee_signature: Vector, -} - -#[derive(Default, SimpleSerialize)] -pub struct SSZForkData { - pub current_version: [u8; 4], - pub genesis_validators_root: [u8; 32], -} - -#[derive(Default, SimpleSerialize)] -pub struct SSZSigningData { - pub object_root: [u8; 32], - pub domain: [u8; 32], -} - -#[derive(Default, SimpleSerialize, Clone, Debug)] -pub struct SSZExecutionPayloadHeader { - pub parent_hash: [u8; 32], - pub fee_recipient: Vector, - pub state_root: [u8; 32], - pub receipts_root: [u8; 32], - pub logs_bloom: Vector, - pub prev_randao: [u8; 32], - pub block_number: u64, - pub gas_limit: u64, - pub gas_used: u64, - pub timestamp: u64, - pub extra_data: List, - pub base_fee_per_gas: U256, - pub block_hash: [u8; 32], - pub transactions_root: [u8; 32], - pub withdrawals_root: [u8; 32], -} diff --git a/parachain/pallets/ethereum-beacon-client/src/tests.rs b/parachain/pallets/ethereum-beacon-client/src/tests.rs index ebd07b865..289d357c4 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -1,549 +1,300 @@ -mod beacon_tests { - use crate as ethereum_beacon_client; - use crate::{ - config, merkleization, - merkleization::MerkleizationError, - mock::*, - ssz::{SSZExecutionPayloadHeader, SSZSyncAggregate}, - BeaconHeader, Error, PublicKey, - }; - use frame_support::{assert_err, assert_ok}; - use hex_literal::hex; - use snowbridge_beacon_primitives::{ExecutionPayloadHeader, SyncAggregate}; - use sp_core::{H256, U256}; - use ssz_rs::prelude::Vector; +use crate::{mock::*, verify_merkle_proof, BeaconHeader, Error}; +use frame_support::{assert_err, assert_ok}; +use hex_literal::hex; - #[test] - pub fn test_get_sync_committee_sum() { - new_tester::().execute_with(|| { - assert_eq!( - mock_minimal::EthereumBeaconClient::get_sync_committee_sum(vec![ - 0, 1, 0, 1, 1, 0, 1, 0, 1 - ]), - 5 - ); - }); - } - - #[test] - pub fn test_compute_domain() { - new_tester::().execute_with(|| { - let domain = mock_minimal::EthereumBeaconClient::compute_domain( - hex!("07000000").into(), - hex!("00000001").into(), - hex!("5dec7ae03261fde20d5b024dfabce8bac3276c9a4908e23d50ba8c9b50b0adff").into(), - ); - - assert_ok!(&domain); - assert_eq!( - domain.unwrap(), - hex!("0700000046324489ceb6ada6d118eacdbe94f49b1fcb49d5481a685979670c7c").into() - ); - }); - } - - #[test] - pub fn test_compute_domain_kiln() { - new_tester::().execute_with(|| { - let domain = mock_minimal::EthereumBeaconClient::compute_domain( - hex!("07000000").into(), - hex!("70000071").into(), - hex!("99b09fcd43e5905236c370f184056bec6e6638cfc31a323b304fc4aa789cb4ad").into(), - ); - - assert_ok!(&domain); - assert_eq!( - domain.unwrap(), - hex!("07000000e7acb21061790987fa1c1e745cccfb358370b33e8af2b2c18938e6c2").into() - ); - }); - } - - #[test] - pub fn test_compute_signing_root_bls() { - new_tester::().execute_with(|| { - let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( - BeaconHeader { - slot: 3529537, - proposer_index: 192549, - parent_root: hex!( - "1f8dc05ea427f78e84e2e2666e13c3befb7106fd1d40ef8a3f67cf615f3f2a4c" - ) - .into(), - state_root: hex!( - "0dfb492a83da711996d2d76b64604f9bca9dc08b6c13cf63b3be91742afe724b" - ) - .into(), - body_root: hex!( - "66fba38f7c8c2526f7ddfe09c1a54dd12ff93bdd4d0df6a0950e88e802228bfa" - ) - .into(), - }, - hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into(), - ); - - assert_ok!(&signing_root); - assert_eq!( - signing_root.unwrap(), - hex!("3ff6e9807da70b2f65cdd58ea1b25ed441a1d589025d2c4091182026d7af08fb").into() - ); - }); - } - - #[test] - pub fn test_compute_signing_root_kiln() { - new_tester::().execute_with(|| { - let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( - BeaconHeader { - slot: 221316, - proposer_index: 79088, - parent_root: hex!( - "b4c15cd79da1a4e645b0104fa66d226cb6dce0fae3522789cc4d0b3ae41d96f7" - ) - .into(), - state_root: hex!( - "6f711ef2e36decbc8f7037e73bbdace42c11f2896a43e44ab8a78dcb2ba66122" - ) - .into(), - body_root: hex!( - "963eaa01341c16dc8f288da47eedad0792978fdaab9f1f97ae0a1103494d1a10" - ) - .into(), - }, - hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into(), - ); - - assert_ok!(&signing_root); - assert_eq!( - signing_root.unwrap(), - hex!("4ce7b4192c0292a2bbf4107766ddc0f613261bb8e6968ccd0e6b71b30fad6d7c").into() - ); - }); - } - - #[test] - pub fn test_compute_signing_root_kiln_head_update() { - new_tester::().execute_with(|| { - let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( - BeaconHeader { - slot: 222472, - proposer_index: 10726, - parent_root: hex!( - "5d481a9721f0ecce9610eab51d400d223683d599b7fcebca7e4c4d10cdef6ebb" - ) - .into(), - state_root: hex!( - "14eb4575895f996a84528b789ff2e4d5148242e2983f03068353b2c37015507a" - ) - .into(), - body_root: hex!( - "7bb669c75b12e0781d6fa85d7fc2f32d64eafba89f39678815b084c156e46cac" - ) - .into(), - }, - hex!("07000000e7acb21061790987fa1c1e745cccfb358370b33e8af2b2c18938e6c2").into(), - ); - - assert_ok!(&signing_root); - assert_eq!( - signing_root.unwrap(), - hex!("da12b6a6d3516bc891e8a49f82fc1925cec40b9327e06457f695035303f55cd8").into() - ); - }); - } - - #[test] - pub fn test_compute_domain_bls() { - new_tester::().execute_with(|| { - let domain = mock_minimal::EthereumBeaconClient::compute_domain( - hex!("07000000").into(), - hex!("01000000").into(), - hex!("4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95").into(), - ); - - assert_ok!(&domain); - assert_eq!( - domain.unwrap(), - hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into() - ); - }); - } - - #[test] - pub fn test_is_valid_merkle_proof() { - new_tester::().execute_with(|| { - assert_eq!( - mock_minimal::EthereumBeaconClient::is_valid_merkle_branch( - hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), - vec![ - hex!("0000000000000000000000000000000000000000000000000000000000000000") - .into(), - hex!("5f6f02af29218292d21a69b64a794a7c0873b3e0f54611972863706e8cbdf371") - .into(), - hex!("e7125ff9ab5a840c44bedb4731f440a405b44e15f2d1a89e27341b432fabe13d") - .into(), - hex!("002c1fe5bc0bd62db6f299a582f2a80a6d5748ccc82e7ed843eaf0ae0739f74a") - .into(), - hex!("d2dc4ba9fd4edff6716984136831e70a6b2e74fca27b8097a820cbbaa5a6e3c3") - .into(), - hex!("91f77a19d8afa4a08e81164bb2e570ecd10477b3b65c305566a6d2be88510584") - .into(), - ] - .to_vec() - .try_into() - .expect("proof branch is too long"), - 6, - 41, - hex!("e46559327592741956f6beaa0f52e49625eb85dce037a0bd2eff333c743b287f").into() - ), - true - ); - }); - } - - #[test] - pub fn test_merkle_proof_fails_if_depth_and_branch_dont_match() { - new_tester::().execute_with(|| { - assert_eq!( - mock_minimal::EthereumBeaconClient::is_valid_merkle_branch( - hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), - vec![ - hex!("0000000000000000000000000000000000000000000000000000000000000000") - .into(), - hex!("5f6f02af29218292d21a69b64a794a7c0873b3e0f54611972863706e8cbdf371") - .into(), - hex!("e7125ff9ab5a840c44bedb4731f440a405b44e15f2d1a89e27341b432fabe13d") - .into(), - ] - .to_vec() - .try_into() - .expect("proof branch is too long"), - 6, - 41, - hex!("e46559327592741956f6beaa0f52e49625eb85dce037a0bd2eff333c743b287f").into() - ), - false - ); - }); - } - - #[test] - pub fn test_bls_fast_aggregate_verify_minimal() { - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( - vec![ - PublicKey(hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into()), - PublicKey(hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into()), - PublicKey(hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into()), - PublicKey(hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into()), - ], - hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), - hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").to_vec().try_into().expect("signature is too long"), - )); - }); - } - - #[test] - pub fn test_bls_fast_aggregate_verify_invalid_point() { - new_tester::().execute_with(|| { - assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( - vec![ - PublicKey(hex!("973eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into()), - PublicKey(hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into()), - PublicKey(hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into()), - PublicKey(hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into()), - ], - hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), - hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").to_vec().try_into().expect("signature is too long"), - ), Error::::InvalidSignaturePoint); +#[test] +pub fn test_get_sync_committee_sum() { + new_tester::().execute_with(|| { + assert_eq!( + mock_minimal::EthereumBeaconClient::get_sync_committee_sum(&[ + 0, 1, 0, 1, 1, 0, 1, 0, 1 + ]), + 5 + ); }); - } +} - #[test] - pub fn test_bls_fast_aggregate_verify_invalid_message() { - new_tester::().execute_with(|| { - assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( - vec![ - PublicKey(hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into()), - PublicKey(hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into()), - PublicKey(hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into()), - PublicKey(hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into()), - ], - hex!("99241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), - hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").to_vec().try_into().expect("signature is too long"), - ), Error::::SignatureVerificationFailed); - }); - } +#[test] +pub fn test_compute_domain() { + new_tester::().execute_with(|| { + let domain = mock_minimal::EthereumBeaconClient::compute_domain( + hex!("07000000").into(), + hex!("00000001").into(), + hex!("5dec7ae03261fde20d5b024dfabce8bac3276c9a4908e23d50ba8c9b50b0adff").into(), + ); - #[test] - pub fn test_bls_fast_aggregate_verify_invalid_signature() { - new_tester::().execute_with(|| { - assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( - vec![ - PublicKey(hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into()), - PublicKey(hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into()), - PublicKey(hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into()), - PublicKey(hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into()), - ], - hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), - hex!("c204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").to_vec().try_into().expect("signature is too long"), - ), Error::::InvalidSignature); + assert_ok!(&domain); + assert_eq!( + domain.unwrap(), + hex!("0700000046324489ceb6ada6d118eacdbe94f49b1fcb49d5481a685979670c7c").into() + ); }); - } - - #[test] - pub fn test_sync_committee_participation_is_supermajority() { - let bits = match config::IS_MINIMAL { - true => hex!("ffffffff").to_vec(), - false => hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7b").to_vec(), - }; - - let sync_committee_bits = merkleization::get_sync_committee_bits::< - mock_minimal::MaxSyncCommitteeSize, - >(bits.try_into().expect("too many sync committee bits")); - - assert_ok!(&sync_committee_bits); +} - assert_ok!( - mock_minimal::EthereumBeaconClient::sync_committee_participation_is_supermajority( - sync_committee_bits.unwrap() - ) +#[test] +pub fn test_compute_domain_kiln() { + new_tester::().execute_with(|| { + let domain = mock_minimal::EthereumBeaconClient::compute_domain( + hex!("07000000").into(), + hex!("70000071").into(), + hex!("99b09fcd43e5905236c370f184056bec6e6638cfc31a323b304fc4aa789cb4ad").into(), ); - } - - #[test] - pub fn test_sync_committee_bits_too_short() { - let bits = match config::IS_MINIMAL { - true => hex!("ffff").to_vec(), - false => hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bffff5f7fedfffdfb6ddff7bf7").to_vec(), - }; - let provided = match config::IS_MINIMAL { - true => 2, - false => 47, - }; - let expected = match config::IS_MINIMAL { - true => 4, - false => 64, - }; - let sync_committee_bits = merkleization::get_sync_committee_bits::< - mock_minimal::MaxSyncCommitteeSize, - >(bits.try_into().expect("invalid sync committee bits")); - - assert_err!( - sync_committee_bits, - MerkleizationError::ExpectedFurtherInput { provided, expected } + assert_ok!(&domain); + assert_eq!( + domain.unwrap(), + hex!("07000000e7acb21061790987fa1c1e745cccfb358370b33e8af2b2c18938e6c2").into() ); - } - - #[test] - pub fn test_sync_committee_bits_extra_input() { - let bits = match config::IS_MINIMAL { - true => hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefff").to_vec(), - false => hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7bf7bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7bf7").to_vec(), - }; - let provided = match config::IS_MINIMAL { - true => 24, - false => 130, - }; - let expected = match config::IS_MINIMAL { - true => 4, - false => 64, - }; - - let sync_committee_bits = merkleization::get_sync_committee_bits::< - mock_minimal::MaxSyncCommitteeSize, - >(bits.try_into().expect("invalid sync committee bits")); + }); +} - assert_err!( - sync_committee_bits, - MerkleizationError::AdditionalInput { provided, expected } +#[test] +pub fn test_compute_signing_root_bls() { + new_tester::().execute_with(|| { + let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( + BeaconHeader { + slot: 3529537, + proposer_index: 192549, + parent_root: hex!( + "1f8dc05ea427f78e84e2e2666e13c3befb7106fd1d40ef8a3f67cf615f3f2a4c" + ) + .into(), + state_root: hex!( + "0dfb492a83da711996d2d76b64604f9bca9dc08b6c13cf63b3be91742afe724b" + ) + .into(), + body_root: hex!("66fba38f7c8c2526f7ddfe09c1a54dd12ff93bdd4d0df6a0950e88e802228bfa") + .into(), + }, + hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into(), ); - } - - #[test] - pub fn test_sync_committee_participation_is_supermajority_errors_when_not_supermajority() { - new_tester::().execute_with(|| { - let sync_committee_bits = vec![ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, - 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, - 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, - 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 0, 0, - ]; - assert_err!( - mock_minimal::EthereumBeaconClient::sync_committee_participation_is_supermajority( - sync_committee_bits - ), - Error::::SyncCommitteeParticipantsNotSupermajority - ); - }); - } + assert_ok!(&signing_root); + assert_eq!( + signing_root.unwrap(), + hex!("3ff6e9807da70b2f65cdd58ea1b25ed441a1d589025d2c4091182026d7af08fb").into() + ); + }); +} - #[test] - pub fn test_hash_tree_root_beacon_header() { - let hash_root = - merkleization::hash_tree_root_beacon_header(ethereum_beacon_client::BeaconHeader { - slot: 3, - proposer_index: 2, +#[test] +pub fn test_compute_signing_root_kiln() { + new_tester::().execute_with(|| { + let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( + BeaconHeader { + slot: 221316, + proposer_index: 79088, parent_root: hex!( - "796ea53efb534eab7777809cc5ee2d84e7f25024b9d0c4d7e5bcaab657e4bdbd" + "b4c15cd79da1a4e645b0104fa66d226cb6dce0fae3522789cc4d0b3ae41d96f7" ) .into(), state_root: hex!( - "ba3ff080912be5c9c158b2e962c1b39a91bc0615762ba6fa2ecacafa94e9ae0a" + "6f711ef2e36decbc8f7037e73bbdace42c11f2896a43e44ab8a78dcb2ba66122" ) .into(), - body_root: hex!("a18d7fcefbb74a177c959160e0ee89c23546482154e6831237710414465dcae5") + body_root: hex!("963eaa01341c16dc8f288da47eedad0792978fdaab9f1f97ae0a1103494d1a10") .into(), - }); + }, + hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into(), + ); - assert_ok!(&hash_root); + assert_ok!(&signing_root); assert_eq!( - hash_root.unwrap(), - hex!("7d42595818709e805dd2fa710a2d2c1f62576ef1ab7273941ac9130fb94b91f7") + signing_root.unwrap(), + hex!("4ce7b4192c0292a2bbf4107766ddc0f613261bb8e6968ccd0e6b71b30fad6d7c").into() ); - } + }); +} - #[test] - pub fn test_hash_tree_root_beacon_header_more_test_values() { - let hash_root = - merkleization::hash_tree_root_beacon_header(ethereum_beacon_client::BeaconHeader { - slot: 3476424, - proposer_index: 314905, +#[test] +pub fn test_compute_signing_root_kiln_head_update() { + new_tester::().execute_with(|| { + let signing_root = mock_minimal::EthereumBeaconClient::compute_signing_root( + BeaconHeader { + slot: 222472, + proposer_index: 10726, parent_root: hex!( - "c069d7b49cffd2b815b0fb8007eb9ca91202ea548df6f3db60000f29b2489f28" + "5d481a9721f0ecce9610eab51d400d223683d599b7fcebca7e4c4d10cdef6ebb" ) .into(), state_root: hex!( - "444d293e4533501ee508ad608783a7d677c3c566f001313e8a02ce08adf590a3" + "14eb4575895f996a84528b789ff2e4d5148242e2983f03068353b2c37015507a" ) .into(), - body_root: hex!("6508a0241047f21ba88f05d05b15534156ab6a6f8e029a9a5423da429834e04a") + body_root: hex!("7bb669c75b12e0781d6fa85d7fc2f32d64eafba89f39678815b084c156e46cac") .into(), - }); + }, + hex!("07000000e7acb21061790987fa1c1e745cccfb358370b33e8af2b2c18938e6c2").into(), + ); - assert_ok!(&hash_root); + assert_ok!(&signing_root); assert_eq!( - hash_root.unwrap(), - hex!("0aa41166ff01e58e111ac8c42309a738ab453cf8d7285ed8477b1c484acb123e") + signing_root.unwrap(), + hex!("da12b6a6d3516bc891e8a49f82fc1925cec40b9327e06457f695035303f55cd8").into() ); - } + }); +} - #[test] - pub fn test_hash_tree_root_fork_data() { - let hash_root = merkleization::hash_tree_root_fork_data(ethereum_beacon_client::ForkData { - current_version: hex!("83f38a34").into(), - genesis_validators_root: hex!( - "22370bbbb358800f5711a10ea9845284272d8493bed0348cab87b8ab1e127930" - ) - .into(), - }); +#[test] +pub fn test_compute_domain_bls() { + new_tester::().execute_with(|| { + let domain = mock_minimal::EthereumBeaconClient::compute_domain( + hex!("07000000").into(), + hex!("01000000").into(), + hex!("4b363db94e286120d76eb905340fdd4e54bfe9f06bf33ff6cf5ad27f511bfe95").into(), + ); - assert_ok!(&hash_root); + assert_ok!(&domain); assert_eq!( - hash_root.unwrap(), - hex!("57c12c4246bc7152b174b51920506bf943eff9c7ffa50b9533708e9cc1f680fc") + domain.unwrap(), + hex!("07000000afcaaba0efab1ca832a15152469bb09bb84641c405171dfa2d3fb45f").into() ); - } + }); +} - #[test] - pub fn test_hash_tree_root_signing_data() { - let hash_root = - merkleization::hash_tree_root_signing_data(ethereum_beacon_client::SigningData { - object_root: hex!( - "63654cbe64fc07853f1198c165dd3d49c54fc53bc417989bbcc66da15f850c54" - ) - .into(), - domain: hex!("037da907d1c3a03c0091b2254e1480d9b1783476e228ab29adaaa8f133e08f7a") - .into(), - }); +#[test] +pub fn test_is_valid_merkle_proof() { + new_tester::().execute_with(|| { + assert_eq!( + verify_merkle_proof( + hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + &[ + hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + hex!("5f6f02af29218292d21a69b64a794a7c0873b3e0f54611972863706e8cbdf371").into(), + hex!("e7125ff9ab5a840c44bedb4731f440a405b44e15f2d1a89e27341b432fabe13d").into(), + hex!("002c1fe5bc0bd62db6f299a582f2a80a6d5748ccc82e7ed843eaf0ae0739f74a").into(), + hex!("d2dc4ba9fd4edff6716984136831e70a6b2e74fca27b8097a820cbbaa5a6e3c3").into(), + hex!("91f77a19d8afa4a08e81164bb2e570ecd10477b3b65c305566a6d2be88510584").into(), + ], + 41, + hex!("e46559327592741956f6beaa0f52e49625eb85dce037a0bd2eff333c743b287f").into() + ), + true + ); + }); +} - assert_ok!(&hash_root); +#[test] +pub fn test_merkle_proof_fails_if_depth_and_branch_dont_match() { + new_tester::().execute_with(|| { assert_eq!( - hash_root.unwrap(), - hex!("b9eb2caf2d691b183c2d57f322afe505c078cd08101324f61c3641714789a54e") + verify_merkle_proof( + hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + &[ + hex!("0000000000000000000000000000000000000000000000000000000000000000").into(), + hex!("5f6f02af29218292d21a69b64a794a7c0873b3e0f54611972863706e8cbdf371").into(), + hex!("e7125ff9ab5a840c44bedb4731f440a405b44e15f2d1a89e27341b432fabe13d").into(), + ], + 41, + hex!("e46559327592741956f6beaa0f52e49625eb85dce037a0bd2eff333c743b287f").into() + ), + false ); - } + }); +} - #[test] - pub fn test_hash_sync_aggregate() { - let sync_aggregate: SyncAggregate = match config::IS_MINIMAL { - true => SyncAggregate{ - sync_committee_bits: hex!("ffffffff").to_vec().try_into().expect("sync committee bits are too long"), - sync_committee_signature: hex!("99b0a4c6b69f17a876c65364e164c74b9cdd75dfd3b7f9b60b850cfb9394091ed501e2c190b8349f1b903bca44dd556a0c20fd9cd34dec3906921f1424359a4870356557b70261eee14bf49d8f3c62dfcdb37206cb34991c379eee46510602bd").to_vec().try_into().expect("signature is too long"), - }, - false => SyncAggregate{ - sync_committee_bits: hex!("cefffffefffffff767fffbedffffeffffeeffdffffdebffffff7f7dbdf7fffdffffbffcfffdff79dfffbbfefff2ffffff7ddeff7ffffc98ff7fbfffffffffff7").to_vec().try_into().expect("sync committee bits are too long"), - sync_committee_signature: hex!("8af1a8577bba419fe054ee49b16ed28e081dda6d3ba41651634685e890992a0b675e20f8d9f2ec137fe9eb50e838aa6117f9f5410e2e1024c4b4f0e098e55144843ce90b7acde52fe7b94f2a1037342c951dc59f501c92acf7ed944cb6d2b5f7").to_vec().try_into().expect("signature is too long"), - }, - }; - let expected_hash_root: H256 = match config::IS_MINIMAL { - true => hex!("6b3a4d0172d3d2075a924b84538621af4a2c9148f26e90e2608a6aae4283e68d").into(), - false => - hex!("e6dcad4f60ce9ff8a587b110facbaf94721f06cd810b6d8bf6cffa641272808d").into(), - }; +#[test] +pub fn test_bls_fast_aggregate_verify_minimal() { + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( + &[ + hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into(), + hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into(), + hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into(), + hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into(), + ], + hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), + &hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").into() + )); + }); +} - let payload: Result = sync_aggregate.try_into(); - assert_ok!(&payload); +#[test] +pub fn test_bls_fast_aggregate_verify_invalid_point() { + new_tester::().execute_with(|| { + assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( + &[ + hex!("973eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into(), + hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into(), + hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into(), + hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into(), + ], + hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), + &hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").into() + ), Error::::InvalidSignaturePoint); + }); +} - let hash_root_result = merkleization::hash_tree_root(payload.unwrap()); - assert_ok!(&hash_root_result); +#[test] +pub fn test_bls_fast_aggregate_verify_invalid_message() { + new_tester::().execute_with(|| { + assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( + &[ + hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into(), + hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into(), + hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into(), + hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into(), + ], + hex!("99241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), + &hex!("b204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").into() + ), Error::::SignatureVerificationFailed); + }); +} - let hash_root: H256 = hash_root_result.unwrap().into(); - assert_eq!(hash_root, expected_hash_root); - } +#[test] +pub fn test_bls_fast_aggregate_verify_invalid_signature() { + new_tester::().execute_with(|| { + assert_err!(mock_minimal::EthereumBeaconClient::bls_fast_aggregate_verify( + &[ + hex!("a73eb991aa22cdb794da6fcde55a427f0a4df5a4a70de23a988b5e5fc8c4d844f66d990273267a54dd21579b7ba6a086").into(), + hex!("b29043a7273d0a2dbc2b747dcf6a5eccbd7ccb44b2d72e985537b117929bc3fd3a99001481327788ad040b4077c47c0d").into(), + hex!("b928f3beb93519eecf0145da903b40a4c97dca00b21f12ac0df3be9116ef2ef27b2ae6bcd4c5bc2d54ef5a70627efcb7").into(), + hex!("9446407bcd8e5efe9f2ac0efbfa9e07d136e68b03c5ebc5bde43db3b94773de8605c30419eb2596513707e4e7448bb50").into(), + ], + hex!("69241e7146cdcc5a5ddc9a60bab8f378c0271e548065a38bcc60624e1dbed97f").into(), + &hex!("c204e9656cbeb79a9a8e397920fd8e60c5f5d9443f58d42186f773c6ade2bd263e2fe6dbdc47f148f871ed9a00b8ac8b17a40d65c8d02120c00dca77495888366b4ccc10f1c6daa02db6a7516555ca0665bca92a647b5f3a514fa083fdc53b6e").into() + ), Error::::InvalidSignature); + }); +} - #[test] - pub fn test_hash_sync_signature() { - let payload = Vector::::from_iter(hex!("82c58d251044ab938b84747524e9b5ecbf6f71f6f1ac10a834806d033bbc49ecd2391072f9bbb4758a960342f8ee03930dc8195f15649c654a56767632230fe3d196f6499d94cd239ba964fe21d7e4715127a385ee018d405719428178172188").to_vec()); +#[test] +pub fn test_sync_committee_participation_is_supermajority() { + let bits = hex!("bffffffff7f1ffdfcfeffeffbfdffffbfffffdffffefefffdffff7f7ffff77fffdf7bff77ffdf7fffafffffff77fefffeff7effffffff5f7fedfffdfb6ddff7b"); + let participation = primitives::decompress_sync_committee_bits::<512, 64>(bits); + assert_ok!(mock_minimal::EthereumBeaconClient::sync_committee_participation_is_supermajority( + &participation + )); +} - let hash_root = merkleization::hash_tree_root(payload); +#[test] +pub fn test_sync_committee_participation_is_supermajority_errors_when_not_supermajority() { + new_tester::().execute_with(|| { + let participation: [u8; 512] = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, + 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, + ]; - assert_eq!( - hash_root.unwrap(), - hex!("2068ede33715fd1eee4a940cea6ebc7d353ea791c18ed0cdc65ab6f4bd367af1") + assert_err!( + mock_minimal::EthereumBeaconClient::sync_committee_participation_is_supermajority( + &participation + ), + Error::::SyncCommitteeParticipantsNotSupermajority ); - } - - #[test] - pub fn test_hash_tree_root_execution_payload() { - let payload: Result = - ExecutionPayloadHeader::{ - parent_hash: hex!("eadee5ab098dde64e9fd02ae5858064bad67064070679625b09f8d82dec183f7").into(), - fee_recipient: hex!("f97e180c050e5ab072211ad2c213eb5aee4df134").to_vec().try_into().expect("fee recipient bits are too long"), - state_root: hex!("564fa064c2a324c2b5978d7fdfc5d4224d4f421a45388af1ed405a399c845dff").into(), - receipts_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), - logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec().try_into().expect("logs bloom is too long"), - prev_randao: hex!("6bf538bdfbdf1c96ff528726a40658a91d0bda0f1351448c4c4f3604db2a0ccf").into(), - block_number: 477434, - gas_limit: 8154925, - gas_used: 0, - timestamp: 1652816940, - extra_data: vec![].try_into().expect("extra data field is too long"), - base_fee_per_gas: U256::from(7 as i16), - block_hash: hex!("cd8df91b4503adb8f2f1c7a4f60e07a1f1a2cbdfa2a95bceba581f3ff65c1968").into(), - transactions_root: hex!("7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1").into(), - withdrawals_root: hex!("28ba1834a3a7b657460ce79fa3a1d909ab8828fd557659d4d0554a9bdbc0ec30").into(), - }.try_into(); - assert_ok!(&payload); - - let hash_root = merkleization::hash_tree_root(payload.unwrap()); - assert_ok!(&hash_root); - } + }); } diff --git a/parachain/pallets/ethereum-beacon-client/src/tests_mainnet.rs b/parachain/pallets/ethereum-beacon-client/src/tests_mainnet.rs index 5f679d4bb..0f38d9e81 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests_mainnet.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests_mainnet.rs @@ -1,207 +1,198 @@ #[cfg(not(feature = "minimal"))] -mod beacon_mainnet_tests { - use crate::{ - config, merkleization, mock::*, Error, ExecutionHeader, ExecutionHeaders, - FinalizedBeaconHeaders, FinalizedBeaconHeadersBlockRoot, FinalizedHeaderState, - LatestFinalizedHeaderState, LatestSyncCommitteePeriod, SyncCommittees, ValidatorsRoot, - }; - use frame_support::{assert_err, assert_ok}; - use hex_literal::hex; - use sp_core::H256; - - #[test] - fn it_syncs_from_an_initial_checkpoint() { - let initial_sync = get_initial_sync::(); - - new_tester::().execute_with(|| { - assert_ok!(mock_mainnet::EthereumBeaconClient::initial_sync(initial_sync.clone())); - - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(initial_sync.header.clone()) - .unwrap() - .into(); - - assert!(>::contains_key(block_root)); - }); - } - - #[test] - fn it_updates_a_committee_period_sync_update() { - let update = get_committee_sync_period_update::(); - - let current_sync_committee = - get_initial_sync::().current_sync_committee; +use crate::{ + config, + config::{SYNC_COMMITTEE_BITS_SIZE, SYNC_COMMITTEE_SIZE}, + mock::*, + Error, ExecutionHeaders, FinalizedBeaconHeaders, FinalizedBeaconHeadersBlockRoot, + FinalizedHeaderState, LatestFinalizedHeaderState, LatestSyncCommitteePeriod, SyncCommittees, + ValidatorsRoot, +}; +use frame_support::{assert_err, assert_ok}; +use hex_literal::hex; +use primitives::decompress_sync_committee_bits; +use sp_core::H256; + +#[test] +fn it_syncs_from_an_initial_checkpoint() { + let initial_sync = get_initial_sync::(); + + new_tester::().execute_with(|| { + assert_ok!(mock_mainnet::EthereumBeaconClient::initial_sync(initial_sync.clone())); + + let block_root: H256 = initial_sync.header.hash_tree_root().unwrap(); + + assert!(>::contains_key(block_root)); + }); +} - let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, +#[test] +fn it_updates_a_committee_period_sync_update() { + let update = + get_committee_sync_period_update::(); + let genesis = get_initial_sync::(); + let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); + + new_tester::().execute_with(|| { + SyncCommittees::::insert( + current_period, + genesis.current_sync_committee, ); + LatestSyncCommitteePeriod::::set(current_period); + ValidatorsRoot::::set(genesis.validators_root); - new_tester::().execute_with(|| { - SyncCommittees::::insert(current_period, current_sync_committee); - LatestSyncCommitteePeriod::::set(current_period); - ValidatorsRoot::::set(get_validators_root::()); + let block_root: H256 = update.finalized_header.hash_tree_root().unwrap(); - assert_ok!(mock_mainnet::EthereumBeaconClient::sync_committee_period_update( - mock_mainnet::RuntimeOrigin::signed(1), - update.clone(), - )); + assert_ok!(mock_mainnet::EthereumBeaconClient::sync_committee_period_update( + mock_mainnet::RuntimeOrigin::signed(1), + update, + )); - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .unwrap() - .into(); + assert!(>::contains_key(block_root)); + }); +} - assert!(>::contains_key(block_root)); +#[test] +fn it_processes_a_finalized_header_update() { + let update = get_finalized_header_update::(); + let genesis = get_initial_sync::(); + let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); + + let slot = update.finalized_header.slot; + let import_time = 1616508000u64 + (slot * config::SECONDS_PER_SLOT); // Goerli genesis time + finalized header update time + let mock_pallet_time = import_time + 3600; // plus one hour + + new_tester::().execute_with(|| { + mock_mainnet::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds + SyncCommittees::::insert( + current_period, + genesis.current_sync_committee, + ); + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: Default::default(), + import_time, + beacon_slot: slot - 1, }); - } + ValidatorsRoot::::set(genesis.validators_root); - #[test] - fn it_processes_a_finalized_header_update() { - let update = get_finalized_header_update::(); - let initial_sync = get_initial_sync::(); - let current_sync_committee = initial_sync.current_sync_committee; + assert_ok!(mock_mainnet::EthereumBeaconClient::import_finalized_header( + mock_mainnet::RuntimeOrigin::signed(1), + update.clone() + )); - let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, - ); + let block_root: H256 = update.finalized_header.hash_tree_root().unwrap(); - let slot = update.finalized_header.slot; - let import_time = 1616508000u64 + (slot * config::SECONDS_PER_SLOT); // Goerli genesis time + finalized header update time - let mock_pallet_time = import_time + 3600; // plus one hour - - new_tester::().execute_with(|| { - mock_mainnet::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds - SyncCommittees::::insert(current_period, current_sync_committee); - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: Default::default(), - import_time, - beacon_slot: slot - 1, - }); - ValidatorsRoot::::set(get_validators_root::()); - - assert_ok!(mock_mainnet::EthereumBeaconClient::import_finalized_header( - mock_mainnet::RuntimeOrigin::signed(1), - update.clone() - )); + assert!(>::contains_key(block_root)); + }); +} - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .unwrap() - .into(); +#[test] +fn it_errors_when_weak_subjectivity_period_exceeded_for_a_finalized_header_update() { + let update = get_finalized_header_update::(); + let genesis = get_initial_sync::(); - assert!(>::contains_key(block_root)); - }); - } + let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); - #[test] - fn it_errors_when_weak_subjectivity_period_exceeded_for_a_finalized_header_update() { - let update = get_finalized_header_update::(); - let initial_sync = get_initial_sync::(); - let current_sync_committee = initial_sync.current_sync_committee; + let slot = update.finalized_header.slot; + let import_time = 1616508000u64 + (slot * config::SECONDS_PER_SLOT); + let mock_pallet_time = import_time + 100800; // plus 28 hours - let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, + new_tester::().execute_with(|| { + mock_mainnet::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds + SyncCommittees::::insert( + current_period, + genesis.current_sync_committee, ); - - let slot = update.finalized_header.slot; - let import_time = 1616508000u64 + (slot * config::SECONDS_PER_SLOT); - let mock_pallet_time = import_time + 100800; // plus 28 hours - - new_tester::().execute_with(|| { - mock_mainnet::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds - SyncCommittees::::insert(current_period, current_sync_committee); - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: Default::default(), - import_time, - beacon_slot: slot - 1, - }); - ValidatorsRoot::::set(get_validators_root::()); - - assert_err!( - mock_mainnet::EthereumBeaconClient::import_finalized_header( - mock_mainnet::RuntimeOrigin::signed(1), - update.clone() - ), - Error::::BridgeBlocked - ); + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: Default::default(), + import_time, + beacon_slot: slot - 1, }); - } + ValidatorsRoot::::set(genesis.validators_root); - #[test] - fn it_processes_a_header_update() { - let update = get_header_update::(); - - let current_sync_committee = - get_initial_sync::().current_sync_committee; - - let current_period = mock_mainnet::EthereumBeaconClient::compute_current_sync_period( - update.beacon_header.slot, - ); - - let finalized_update = get_finalized_header_update::(); - let finalized_slot = finalized_update.finalized_header.slot; - let finalized_block_root: H256 = - merkleization::hash_tree_root_beacon_header(finalized_update.finalized_header) - .unwrap() - .into(); - - new_tester::().execute_with(|| { - SyncCommittees::::insert(current_period, current_sync_committee); - ValidatorsRoot::::set(get_validators_root::()); - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: finalized_block_root, - beacon_slot: finalized_slot, - import_time: 0, - }); - FinalizedBeaconHeadersBlockRoot::::insert( - finalized_block_root, - finalized_update.block_roots_root, - ); - - assert_ok!(mock_mainnet::EthereumBeaconClient::import_execution_header( + assert_err!( + mock_mainnet::EthereumBeaconClient::import_finalized_header( mock_mainnet::RuntimeOrigin::signed(1), update.clone() - )); - - let execution_header: ExecutionHeader = update.execution_header.try_into().unwrap(); + ), + Error::::BridgeBlocked + ); + }); +} - assert!(>::contains_key( - execution_header.block_hash - )); +#[test] +fn it_processes_a_header_update() { + let update = get_header_update::(); + let genesis = get_initial_sync::(); + let current_period = + mock_mainnet::EthereumBeaconClient::compute_current_sync_period(update.beacon_header.slot); + + let finalized_update = + get_finalized_header_update::(); + let finalized_slot = finalized_update.finalized_header.slot; + let finalized_block_root: H256 = finalized_update.finalized_header.hash_tree_root().unwrap(); + + new_tester::().execute_with(|| { + SyncCommittees::::insert( + current_period, + genesis.current_sync_committee, + ); + ValidatorsRoot::::set(genesis.validators_root); + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: finalized_block_root, + beacon_slot: finalized_slot, + import_time: 0, }); - } - - #[test] - pub fn test_hash_tree_root_sync_committee() { - let sync_committee = get_committee_sync_ssz_test_data::(); - let hash_root_result = merkleization::hash_tree_root_sync_committee(sync_committee); - assert_ok!(&hash_root_result); - - let hash_root: H256 = hash_root_result.unwrap().into(); - assert_eq!( - hash_root, - hex!("99daf976424b62249669bc842e9b8e5a5a2960d1d81d98c3267f471409c3c841").into() + FinalizedBeaconHeadersBlockRoot::::insert( + finalized_block_root, + finalized_update.block_roots_root, ); - } - - #[test] - pub fn test_bls_fast_aggregate_verify() { - let test_data = get_bls_signature_verify_test_data::(); - - let sync_committee_bits = - merkleization::get_sync_committee_bits::( - test_data.sync_committee_bits.try_into().expect("too many sync committee bits"), - ); - - assert_ok!(&sync_committee_bits); - - assert_ok!(mock_mainnet::EthereumBeaconClient::verify_signed_header( - sync_committee_bits.unwrap(), - test_data.sync_committee_signature.try_into().expect("signature is too long"), - test_data.pubkeys.to_vec().try_into().expect("to many pubkeys"), - test_data.header, - test_data.validators_root, - test_data.signature_slot, + + assert_ok!(mock_mainnet::EthereumBeaconClient::import_execution_header( + mock_mainnet::RuntimeOrigin::signed(1), + update.clone() + )); + + assert!(>::contains_key( + update.execution_header.block_hash )); - } + }); +} + +#[test] +pub fn test_hash_tree_root_sync_committee() { + let sync_committee = get_committee_sync_ssz_test_data::(); + let hash_root_result = sync_committee.hash_tree_root(); + assert_ok!(&hash_root_result); + + let hash_root: H256 = hash_root_result.unwrap().into(); + assert_eq!( + hash_root, + hex!("99daf976424b62249669bc842e9b8e5a5a2960d1d81d98c3267f471409c3c841").into() + ); +} + +#[test] +pub fn test_bls_fast_aggregate_verify() { + let test_data = + get_bls_signature_verify_test_data::(); + + let participation = decompress_sync_committee_bits::< + SYNC_COMMITTEE_SIZE, + SYNC_COMMITTEE_BITS_SIZE, + >(test_data.sync_committee_bits); + + assert_ok!(mock_mainnet::EthereumBeaconClient::verify_signed_header( + &participation, + &test_data.sync_committee_signature, + &test_data.pubkeys, + test_data.header, + test_data.validators_root, + test_data.signature_slot, + )); } diff --git a/parachain/pallets/ethereum-beacon-client/src/tests_minimal.rs b/parachain/pallets/ethereum-beacon-client/src/tests_minimal.rs index 32f8f464b..f3774b2b9 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests_minimal.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests_minimal.rs @@ -1,403 +1,388 @@ -#[cfg(feature = "minimal")] -mod beacon_minimal_tests { - use crate::{ - config, merkleization, mock::*, pallet::FinalizedBeaconHeadersBlockRoot, Error, - ExecutionHeader, ExecutionHeaderState, ExecutionHeaders, FinalizedBeaconHeaders, - FinalizedHeaderState, LatestExecutionHeaderState, LatestFinalizedHeaderState, - LatestSyncCommitteePeriod, SyncCommittees, ValidatorsRoot, - }; - use frame_support::{assert_err, assert_ok}; - use hex_literal::hex; - use sp_core::H256; - use std::time::{SystemTime, UNIX_EPOCH}; - - #[test] - fn it_syncs_from_an_initial_checkpoint() { - let initial_sync = get_initial_sync::(); - - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); - - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(initial_sync.header.clone()) - .unwrap() - .into(); - - assert!(>::contains_key(block_root)); - }); - } +use crate::{ + config, + config::{SYNC_COMMITTEE_BITS_SIZE, SYNC_COMMITTEE_SIZE}, + mock::*, + pallet::FinalizedBeaconHeadersBlockRoot, + Error, ExecutionHeaderState, ExecutionHeaders, FinalizedBeaconHeaders, FinalizedHeaderState, + LatestExecutionHeaderState, LatestFinalizedHeaderState, LatestSyncCommitteePeriod, + SyncCommittees, ValidatorsRoot, +}; +use frame_support::{assert_err, assert_ok}; +use hex_literal::hex; +use primitives::decompress_sync_committee_bits; +use sp_core::H256; +use std::time::{SystemTime, UNIX_EPOCH}; + +#[test] +fn it_syncs_from_an_initial_checkpoint() { + let initial_sync = get_initial_sync::(); + + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); + + let block_root: H256 = initial_sync.header.hash_tree_root().unwrap(); + + assert!(>::contains_key(block_root)); + }); +} - #[test] - fn it_updates_a_committee_period_sync_update() { - let initial_sync = get_initial_sync::(); +#[test] +fn it_updates_a_committee_period_sync_update() { + let initial_sync = get_initial_sync::(); - let update = get_committee_sync_period_update::(); + let update = + get_committee_sync_period_update::(); - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); - let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, - ); + let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); - SyncCommittees::::insert( - current_period, - initial_sync.current_sync_committee, - ); + SyncCommittees::::insert( + current_period, + initial_sync.current_sync_committee, + ); - LatestSyncCommitteePeriod::::set(current_period); + LatestSyncCommitteePeriod::::set(current_period); + + assert_ok!(mock_minimal::EthereumBeaconClient::sync_committee_period_update( + mock_minimal::RuntimeOrigin::signed(1), + update.clone(), + )); + + let block_root: H256 = update.finalized_header.hash_tree_root().unwrap(); + + assert!(>::contains_key(block_root)); + }); +} - assert_ok!(mock_minimal::EthereumBeaconClient::sync_committee_period_update( +#[test] +fn it_updates_a_committee_period_sync_update_with_invalid_header() { + let initial_sync = get_initial_sync::(); + + let mut update = + get_committee_sync_period_update::(); + + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); + + // makes a invalid update with signature_slot should be more than attested_slot + update.signature_slot = update.attested_header.slot; + + assert_err!( + mock_minimal::EthereumBeaconClient::sync_committee_period_update( mock_minimal::RuntimeOrigin::signed(1), update.clone(), - )); + ), + Error::::InvalidSyncCommitteeHeaderUpdate + ); + }); +} - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .unwrap() - .into(); +/* +#[test] +fn it_updates_a_invalid_committee_period_sync_update_with_gap() { + let initial_sync = get_initial_sync::(); - assert!(>::contains_key(block_root)); - }); - } + let update = get_committee_sync_period_update::(); - #[test] - fn it_updates_a_committee_period_sync_update_with_invalid_header() { - let initial_sync = get_initial_sync::(); + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); - let mut update = get_committee_sync_period_update::(); + let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); + SyncCommittees::::insert( + current_period, + initial_sync.current_sync_committee, + ); + + assert_err!( + mock_minimal::EthereumBeaconClient::sync_committee_period_update( + mock_minimal::RuntimeOrigin::signed(1), + update.clone(), + ), + Error::::InvalidSyncCommitteeUpdateWithGap + ); + }); +} +*/ - // makes a invalid update with signature_slot should be more than attested_slot - update.signature_slot = update.attested_header.slot; +#[test] +fn it_updates_a_invalid_committee_period_sync_update_with_duplicate_entry() { + let initial_sync = get_initial_sync::(); - assert_err!( - mock_minimal::EthereumBeaconClient::sync_committee_period_update( - mock_minimal::RuntimeOrigin::signed(1), - update.clone(), - ), - Error::::InvalidSyncCommitteeHeaderUpdate - ); - }); - } - - /* - #[test] - fn it_updates_a_invalid_committee_period_sync_update_with_gap() { - let initial_sync = get_initial_sync::(); - - let update = get_committee_sync_period_update::(); - - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); - - let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, - ); - - SyncCommittees::::insert( - current_period, - initial_sync.current_sync_committee, - ); - - assert_err!( - mock_minimal::EthereumBeaconClient::sync_committee_period_update( - mock_minimal::RuntimeOrigin::signed(1), - update.clone(), - ), - Error::::InvalidSyncCommitteePeriodUpdateWithGap - ); - }); - } - */ - - #[test] - fn it_updates_a_invalid_committee_period_sync_update_with_duplicate_entry() { - let initial_sync = get_initial_sync::(); - - let update = get_committee_sync_period_update::(); - - new_tester::().execute_with(|| { - assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); - - let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( - update.attested_header.slot, - ); - - SyncCommittees::::insert( - current_period, - initial_sync.current_sync_committee.clone(), - ); - - // initialize with period of the next update - SyncCommittees::::insert( - current_period + 1, - initial_sync.current_sync_committee, - ); - - LatestSyncCommitteePeriod::::set(current_period + 1); - - assert_err!( - mock_minimal::EthereumBeaconClient::sync_committee_period_update( - mock_minimal::RuntimeOrigin::signed(1), - update.clone(), - ), - Error::::InvalidSyncCommitteePeriodUpdateWithDuplication - ); - }); - } + let update = + get_committee_sync_period_update::(); - #[test] - fn it_processes_a_finalized_header_update() { - let update = get_finalized_header_update::(); - let initial_sync = get_initial_sync::(); - let current_sync_committee = initial_sync.current_sync_committee; + new_tester::().execute_with(|| { + assert_ok!(mock_minimal::EthereumBeaconClient::initial_sync(initial_sync.clone())); let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( update.attested_header.slot, ); - let time_now = SystemTime::now() - .duration_since(UNIX_EPOCH) - .expect("Time went backwards") - .as_secs(); - - let import_time = time_now + (update.finalized_header.slot * config::SECONDS_PER_SLOT); // Goerli genesis time + finalized header update time - let mock_pallet_time = import_time + 3600; // plus one hour - - new_tester::().execute_with(|| { - mock_minimal::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: Default::default(), - import_time, - // set the last imported finalized header to an older finalized header. Necessary - // for long range attack check and finalized header to be imported must not have - // been imported already. - beacon_slot: update.finalized_header.slot - 1, - }); - SyncCommittees::::insert(current_period, current_sync_committee); - ValidatorsRoot::::set(get_validators_root::()); - - assert_ok!(mock_minimal::EthereumBeaconClient::import_finalized_header( + SyncCommittees::::insert( + current_period, + initial_sync.current_sync_committee.clone(), + ); + + // initialize with period of the next update + SyncCommittees::::insert( + current_period + 1, + initial_sync.current_sync_committee, + ); + + LatestSyncCommitteePeriod::::set(current_period + 1); + + assert_err!( + mock_minimal::EthereumBeaconClient::sync_committee_period_update( mock_minimal::RuntimeOrigin::signed(1), - update.clone() - )); + update.clone(), + ), + Error::::InvalidSyncCommitteeUpdateWithDuplication + ); + }); +} + +#[test] +fn it_processes_a_finalized_header_update() { + let update = get_finalized_header_update::(); + let initial_sync = get_initial_sync::(); + let current_sync_committee = initial_sync.current_sync_committee; + + let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( + update.attested_header.slot, + ); + + let time_now = SystemTime::now() + .duration_since(UNIX_EPOCH) + .expect("Time went backwards") + .as_secs(); + + let import_time = time_now + (update.finalized_header.slot * config::SECONDS_PER_SLOT); // Goerli genesis time + finalized header update time + let mock_pallet_time = import_time + 3600; // plus one hour + + new_tester::().execute_with(|| { + mock_minimal::Timestamp::set_timestamp(mock_pallet_time * 1000); // needs to be in milliseconds + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: Default::default(), + import_time, + // set the last imported finalized header to an older finalized header. Necessary + // for long range attack check and finalized header to be imported must not have + // been imported already. + beacon_slot: update.finalized_header.slot - 1, + }); + SyncCommittees::::insert(current_period, current_sync_committee); + ValidatorsRoot::::set(get_validators_root::()); - let block_root: H256 = - merkleization::hash_tree_root_beacon_header(update.finalized_header.clone()) - .unwrap() - .into(); + assert_ok!(mock_minimal::EthereumBeaconClient::import_finalized_header( + mock_minimal::RuntimeOrigin::signed(1), + update.clone() + )); + + let block_root: H256 = update.finalized_header.clone().hash_tree_root().unwrap(); + + assert!(>::contains_key(block_root)); + }); +} + +#[test] +fn it_processes_a_invalid_finalized_header_update() { + let update = get_finalized_header_update::(); - assert!(>::contains_key(block_root)); + new_tester::().execute_with(|| { + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: Default::default(), + import_time: 0, + // initialize with the same slot as the next updating + beacon_slot: update.finalized_header.slot, }); - } - - #[test] - fn it_processes_a_invalid_finalized_header_update() { - let update = get_finalized_header_update::(); - - new_tester::().execute_with(|| { - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: Default::default(), - import_time: 0, - // initialize with the same slot as the next updating - beacon_slot: update.finalized_header.slot, - }); - - // update with same slot as last finalized will fail - assert_err!( - mock_minimal::EthereumBeaconClient::import_finalized_header( - mock_minimal::RuntimeOrigin::signed(1), - update.clone() - ), - Error::::DuplicateFinalizedHeaderUpdate - ); + + // update with same slot as last finalized will fail + assert_err!( + mock_minimal::EthereumBeaconClient::import_finalized_header( + mock_minimal::RuntimeOrigin::signed(1), + update.clone() + ), + Error::::DuplicateFinalizedHeaderUpdate + ); + }); +} + +/* +#[test] +fn it_processes_a_invalid_finalized_header_update_with_period_gap() { + let initial_sync = get_initial_sync::(); + let update = get_finalized_header_update::(); + + new_tester::().execute_with(|| { + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: Default::default(), + import_time: 0, + // initialize last_finalized_slot as period 0 + beacon_slot: 1, }); - } - - /* - #[test] - fn it_processes_a_invalid_finalized_header_update_with_period_gap() { - let initial_sync = get_initial_sync::(); - let update = get_finalized_header_update::(); - - new_tester::().execute_with(|| { - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: Default::default(), - import_time: 0, - // initialize last_finalized_slot as period 0 - beacon_slot: 1, - }); - SyncCommittees::::insert(0, initial_sync.current_sync_committee); - ValidatorsRoot::::set(get_validators_root::()); - - // update with period 2 to make period gap check fail - assert_err!( - mock_minimal::EthereumBeaconClient::import_finalized_header( - mock_minimal::RuntimeOrigin::signed(1), - update.clone() - ), - Error::::InvalidFinalizedPeriodUpdate - ); + SyncCommittees::::insert(0, initial_sync.current_sync_committee); + ValidatorsRoot::::set(get_validators_root::()); + + // update with period 2 to make period gap check fail + assert_err!( + mock_minimal::EthereumBeaconClient::import_finalized_header( + mock_minimal::RuntimeOrigin::signed(1), + update.clone() + ), + Error::::InvalidFinalizedPeriodUpdate + ); + }); +}*/ + +#[test] +fn it_processes_a_header_update() { + let update = get_header_update::(); + + let current_sync_committee = get_initial_sync::().current_sync_committee; + + let finalized_update = + get_finalized_header_update::(); + let finalized_slot = finalized_update.finalized_header.slot; + let finalized_block_root: H256 = finalized_update.finalized_header.hash_tree_root().unwrap(); + + let current_period = + mock_minimal::EthereumBeaconClient::compute_current_sync_period(update.beacon_header.slot); + + new_tester::().execute_with(|| { + SyncCommittees::::insert(current_period, current_sync_committee); + ValidatorsRoot::::set(get_validators_root::()); + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: finalized_block_root, + beacon_slot: finalized_slot, + import_time: 0, }); - }*/ + FinalizedBeaconHeadersBlockRoot::::insert( + finalized_block_root, + finalized_update.block_roots_root, + ); - #[test] - fn it_processes_a_header_update() { - let update = get_header_update::(); + assert_ok!(mock_minimal::EthereumBeaconClient::import_execution_header( + mock_minimal::RuntimeOrigin::signed(1), + update.clone() + )); - let current_sync_committee = - get_initial_sync::().current_sync_committee; + assert!(>::contains_key( + update.execution_header.block_hash + )); + }); +} - let finalized_update = get_finalized_header_update::(); - let finalized_slot = finalized_update.finalized_header.slot; - let finalized_block_root: H256 = - merkleization::hash_tree_root_beacon_header(finalized_update.finalized_header) - .unwrap() - .into(); +#[test] +fn it_processes_a_invalid_header_update_not_finalized() { + let update = get_header_update::(); - let current_period = mock_minimal::EthereumBeaconClient::compute_current_sync_period( - update.beacon_header.slot, - ); + new_tester::().execute_with(|| { + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: H256::default(), + // initialize finalized state with parent slot of the next update + beacon_slot: update.beacon_header.slot - 1, + import_time: 0, + }); - new_tester::().execute_with(|| { - SyncCommittees::::insert(current_period, current_sync_committee); - ValidatorsRoot::::set(get_validators_root::()); - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: finalized_block_root, - beacon_slot: finalized_slot, - import_time: 0, - }); - FinalizedBeaconHeadersBlockRoot::::insert( - finalized_block_root, - finalized_update.block_roots_root, - ); - - assert_ok!(mock_minimal::EthereumBeaconClient::import_execution_header( + assert_err!( + mock_minimal::EthereumBeaconClient::import_execution_header( mock_minimal::RuntimeOrigin::signed(1), update.clone() - )); + ), + Error::::HeaderNotFinalized + ); + }); +} - let execution_header: ExecutionHeader = update.execution_header.try_into().unwrap(); +#[test] +fn it_processes_a_invalid_header_update_with_duplicate_entry() { + let update = get_header_update::(); - assert!(>::contains_key( - execution_header.block_hash - )); + new_tester::().execute_with(|| { + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: H256::default(), + beacon_slot: update.beacon_header.slot, + import_time: 0, }); - } - - #[test] - fn it_processes_a_invalid_header_update_not_finalized() { - let update = get_header_update::(); - - new_tester::().execute_with(|| { - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: H256::default(), - // initialize finalized state with parent slot of the next update - beacon_slot: update.beacon_header.slot - 1, - import_time: 0, - }); - - assert_err!( - mock_minimal::EthereumBeaconClient::import_execution_header( - mock_minimal::RuntimeOrigin::signed(1), - update.clone() - ), - Error::::HeaderNotFinalized - ); - }); - } - - #[test] - fn it_processes_a_invalid_header_update_with_duplicate_entry() { - let update = get_header_update::(); - - new_tester::().execute_with(|| { - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: H256::default(), - beacon_slot: update.beacon_header.slot, - import_time: 0, - }); - - let execution_header: ExecutionHeader = - update.execution_header.clone().try_into().unwrap(); - - LatestExecutionHeaderState::::set(ExecutionHeaderState { - beacon_block_root: Default::default(), - beacon_slot: 0, - block_hash: Default::default(), - // initialize with the same block_number in execution_payload of the next update - block_number: execution_header.block_number, - }); - - assert_err!( - mock_minimal::EthereumBeaconClient::import_execution_header( - mock_minimal::RuntimeOrigin::signed(1), - update - ), - Error::::InvalidExecutionHeaderUpdate - ); + + LatestExecutionHeaderState::::set(ExecutionHeaderState { + beacon_block_root: Default::default(), + beacon_slot: 0, + block_hash: Default::default(), + // initialize with the same block_number in execution_payload of the next update + block_number: update.execution_header.block_number, }); - } - - #[test] - fn it_errors_when_importing_a_header_with_no_sync_committee_for_period() { - let update = get_finalized_header_update::(); - - new_tester::().execute_with(|| { - ValidatorsRoot::::set( - hex!("99b09fcd43e5905236c370f184056bec6e6638cfc31a323b304fc4aa789cb4ad").into(), - ); - - LatestFinalizedHeaderState::::set(FinalizedHeaderState { - beacon_block_root: H256::default(), - beacon_slot: update.finalized_header.slot - 1, - import_time: 0, - }); - - assert_err!( - mock_minimal::EthereumBeaconClient::import_finalized_header( - mock_minimal::RuntimeOrigin::signed(1), - update - ), - Error::::SyncCommitteeMissing - ); + + assert_err!( + mock_minimal::EthereumBeaconClient::import_execution_header( + mock_minimal::RuntimeOrigin::signed(1), + update + ), + Error::::InvalidExecutionHeaderUpdate + ); + }); +} + +#[test] +fn it_errors_when_importing_a_header_with_no_sync_committee_for_period() { + let update = get_finalized_header_update::(); + + new_tester::().execute_with(|| { + ValidatorsRoot::::set( + hex!("99b09fcd43e5905236c370f184056bec6e6638cfc31a323b304fc4aa789cb4ad").into(), + ); + + LatestFinalizedHeaderState::::set(FinalizedHeaderState { + beacon_block_root: H256::default(), + beacon_slot: update.finalized_header.slot - 1, + import_time: 0, }); - } - - #[test] - pub fn test_hash_tree_root_sync_committee() { - let sync_committee = get_committee_sync_ssz_test_data::(); - let hash_root_result = merkleization::hash_tree_root_sync_committee(sync_committee); - assert_ok!(&hash_root_result); - - let hash_root: H256 = hash_root_result.unwrap().into(); - assert_eq!( - hash_root, - hex!("7ba44032b68620539b1bac45e5202dd530af5f6b669a5a496ba0fcfb3f0b8da3").into() + + assert_err!( + mock_minimal::EthereumBeaconClient::import_finalized_header( + mock_minimal::RuntimeOrigin::signed(1), + update + ), + Error::::SyncCommitteeMissing ); - } - - #[test] - pub fn test_bls_fast_aggregate_verify() { - let test_data = get_bls_signature_verify_test_data::(); - - let sync_committee_bits = - merkleization::get_sync_committee_bits::( - test_data.sync_committee_bits.try_into().expect("too many sync committee bits"), - ); - - assert_ok!(&sync_committee_bits); - - assert_ok!(mock_minimal::EthereumBeaconClient::verify_signed_header( - sync_committee_bits.unwrap(), - test_data.sync_committee_signature.try_into().expect("signature is too long"), - test_data.pubkeys.to_vec().try_into().expect("to many pubkeys"), - test_data.header, - test_data.validators_root, - test_data.signature_slot, - )); - } + }); +} + +#[test] +pub fn test_hash_tree_root_sync_committee() { + let sync_committee = get_committee_sync_ssz_test_data::(); + let hash_root_result = sync_committee.hash_tree_root(); + assert_ok!(&hash_root_result); + + let hash_root: H256 = hash_root_result.unwrap().into(); + assert_eq!( + hash_root, + hex!("7ba44032b68620539b1bac45e5202dd530af5f6b669a5a496ba0fcfb3f0b8da3").into() + ); +} + +#[test] +pub fn test_bls_fast_aggregate_verify() { + let test_data = + get_bls_signature_verify_test_data::(); + + let participation = decompress_sync_committee_bits::< + SYNC_COMMITTEE_SIZE, + SYNC_COMMITTEE_BITS_SIZE, + >(test_data.sync_committee_bits); + + assert_ok!(mock_minimal::EthereumBeaconClient::verify_signed_header( + &participation, + &test_data.sync_committee_signature, + &test_data.pubkeys, + test_data.header, + test_data.validators_root, + test_data.signature_slot, + )); } diff --git a/parachain/primitives/beacon/Cargo.toml b/parachain/primitives/beacon/Cargo.toml index ddc9dc709..ba4698a4c 100644 --- a/parachain/primitives/beacon/Cargo.toml +++ b/parachain/primitives/beacon/Cargo.toml @@ -1,14 +1,16 @@ [package] name = "snowbridge-beacon-primitives" version = "0.0.1" -authors = [ "Snowfork " ] +authors = ["Snowfork "] edition = "2021" [dependencies] -serde = { version = "1.0.160", optional = true, features = [ "derive" ] } +serde = { version = "1.0.160", optional = true, features = ["derive"] } hex = { version = "0.4", default-features = false } codec = { package = "parity-scale-codec", version = "3.1.5", default-features = false } -scale-info = { version = "2.5.0", default-features = false, features = [ "derive" ] } +scale-info = { version = "2.5.0", default-features = false, features = [ + "derive", +] } rlp = { version = "0.5", default-features = false } frame-support = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } @@ -18,10 +20,18 @@ sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "master sp-core = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } sp-io = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } +ssz-rs = { git = "https://github.com/ralexstokes/ssz-rs", default-features = false, rev = "d18af912abacbf84219be37ab3b42a9abcf10d2a" } +ssz-rs-derive = { git = "https://github.com/ralexstokes/ssz-rs", default-features = false, rev = "d18af912abacbf84219be37ab3b42a9abcf10d2a" } +byte-slice-cast = { version = "1.2.1", default-features = false } + snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } +static_assertions = { version = "1.1.0" } + +[dev-dependencies] +hex-literal = { version = "0.4.1" } [features] -default = [ "std" ] +default = ["std"] std = [ "serde", "codec/std", @@ -34,4 +44,6 @@ std = [ "sp-io/std", "rlp/std", "snowbridge-ethereum/std", + "ssz-rs/std", + "byte-slice-cast/std", ] diff --git a/parachain/primitives/beacon/src/bits.rs b/parachain/primitives/beacon/src/bits.rs new file mode 100644 index 000000000..f8bcb92aa --- /dev/null +++ b/parachain/primitives/beacon/src/bits.rs @@ -0,0 +1,17 @@ +use sp_std::{convert::TryInto, prelude::*}; +use ssz_rs::{Bitvector, Deserialize}; + +pub fn decompress_sync_committee_bits< + const SYNC_COMMITTEE_SIZE: usize, + const SYNC_COMMITTEE_BITS_SIZE: usize, +>( + input: [u8; SYNC_COMMITTEE_BITS_SIZE], +) -> [u8; SYNC_COMMITTEE_SIZE] { + Bitvector::<{ SYNC_COMMITTEE_SIZE }>::deserialize(&input) + .expect("checked statically; qed") + .iter() + .map(|bit| u8::from(bit == true)) + .collect::>() + .try_into() + .expect("checked statically; qed") +} diff --git a/parachain/primitives/beacon/src/config.rs b/parachain/primitives/beacon/src/config.rs new file mode 100644 index 000000000..37d023de8 --- /dev/null +++ b/parachain/primitives/beacon/src/config.rs @@ -0,0 +1,8 @@ +pub const MAX_PROOF_SIZE: u32 = 20; + +pub const FEE_RECIPIENT_SIZE: usize = 20; +pub const EXTRA_DATA_SIZE: usize = 32; +pub const LOGS_BLOOM_SIZE: usize = 256; + +pub const PUBKEY_SIZE: usize = 48; +pub const SIGNATURE_SIZE: usize = 96; diff --git a/parachain/primitives/beacon/src/lib.rs b/parachain/primitives/beacon/src/lib.rs index 39add3c20..e3810bd07 100644 --- a/parachain/primitives/beacon/src/lib.rs +++ b/parachain/primitives/beacon/src/lib.rs @@ -1,498 +1,23 @@ #![cfg_attr(not(feature = "std"), no_std)] -use codec::{Decode, Encode, MaxEncodedLen}; -use frame_support::{traits::Get, BoundedVec, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; -use scale_info::TypeInfo; -use snowbridge_ethereum::mpt; -use sp_core::{H160, H256, U256}; -use sp_io::hashing::keccak_256; -use sp_runtime::RuntimeDebug; -use sp_std::prelude::*; - -#[cfg(feature = "std")] -use core::fmt::Formatter; -#[cfg(feature = "std")] -use serde::{de::Error, de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; -#[cfg(feature = "std")] -use sp_std::fmt::Result as StdResult; - -pub type Root = H256; -pub type Domain = H256; -pub type ValidatorIndex = u64; -pub type ForkVersion = [u8; 4]; - -#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] -pub struct ForkVersions { - pub genesis: Fork, - pub altair: Fork, - pub bellatrix: Fork, - pub capella: Fork, -} - -#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] -pub struct Fork { - pub version: [u8; 4], - pub epoch: u64, -} - -#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] -pub struct PublicKey(pub [u8; 48]); - -impl, ProofSize: Get> Default - for InitialSync -{ - fn default() -> Self { - InitialSync { - header: Default::default(), - current_sync_committee: Default::default(), - current_sync_committee_branch: Default::default(), - validators_root: Default::default(), - import_time: Default::default(), - } - } -} - -impl> Default for SyncCommittee { - fn default() -> Self { - SyncCommittee { pubkeys: Default::default(), aggregate_pubkey: Default::default() } - } -} - -impl Default for PublicKey { - fn default() -> Self { - PublicKey([0u8; 48]) - } -} - -impl MaxEncodedLen for PublicKey { - fn max_encoded_len() -> usize { - 48 - } -} - -#[cfg(feature = "std")] -impl Serialize for PublicKey { - fn serialize(&self, serializer: S) -> Result - where - S: Serializer, - { - serializer.serialize_bytes(&self.0) - } -} - -struct PublicKeyVisitor; - -#[cfg(feature = "std")] -impl<'de> Visitor<'de> for PublicKeyVisitor { - type Value = PublicKey; - - fn expecting(&self, formatter: &mut Formatter) -> StdResult { - formatter.write_str("a hex string") - } - - fn visit_str(self, v: &str) -> Result - where - E: Error, - { - let str_without_0x = match v.strip_prefix("0x") { - Some(val) => val, - None => v, - }; - - let hex_bytes = match hex::decode(str_without_0x) { - Ok(bytes) => bytes, - Err(e) => return Err(Error::custom(e.to_string())), - }; - if hex_bytes.len() != 48 { - return Err(Error::custom("publickey expected to be 48 characters")) - } - - let mut data = [0u8; 48]; - data[0..48].copy_from_slice(&hex_bytes); - Ok(PublicKey(data)) - } -} - -#[cfg(feature = "std")] -impl<'de> Deserialize<'de> for PublicKey { - fn deserialize(deserializer: D) -> Result - where - D: Deserializer<'de>, - { - deserializer.deserialize_str(PublicKeyVisitor) - } -} - -#[derive(Default, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct ExecutionHeaderState { - pub beacon_block_root: H256, - pub beacon_slot: u64, - pub block_hash: H256, - pub block_number: u64, -} - -#[derive(Default, Encode, Decode, TypeInfo, MaxEncodedLen)] -pub struct FinalizedHeaderState { - pub beacon_block_root: H256, - pub beacon_slot: u64, - pub import_time: u64, -} - -#[derive( - Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(SyncCommitteeSize, ProofSize))] -#[codec(mel_bound())] -pub struct InitialSync, ProofSize: Get> { - pub header: BeaconHeader, - pub current_sync_committee: SyncCommittee, - pub current_sync_committee_branch: BoundedVec, - pub validators_root: Root, - pub import_time: u64, -} - -#[derive( - Default, - Encode, - Decode, - CloneNoBound, - PartialEqNoBound, - RuntimeDebugNoBound, - TypeInfo, - MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(SignatureSize, ProofSize, SyncCommitteeSize, SyncCommitteeSize))] -#[codec(mel_bound())] -pub struct SyncCommitteePeriodUpdate< - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, -> { - pub attested_header: BeaconHeader, - pub next_sync_committee: SyncCommittee, - pub next_sync_committee_branch: BoundedVec, - pub finalized_header: BeaconHeader, - pub finality_branch: BoundedVec, - pub sync_aggregate: SyncAggregate, - pub sync_committee_period: u64, - pub signature_slot: u64, - pub block_roots_root: H256, - pub block_roots_branch: BoundedVec, -} - -#[derive( - Default, - Encode, - Decode, - CloneNoBound, - PartialEqNoBound, - RuntimeDebugNoBound, - TypeInfo, - MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(serde::Serialize, serde::Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(SignatureSize, ProofSize, SyncCommitteeSize,))] -#[codec(mel_bound())] -pub struct FinalizedHeaderUpdate< - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, -> { - pub attested_header: BeaconHeader, - pub finalized_header: BeaconHeader, - pub finality_branch: BoundedVec, - pub sync_aggregate: SyncAggregate, - pub signature_slot: u64, - pub block_roots_root: H256, - pub block_roots_branch: BoundedVec, -} - -#[derive( - Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params( - FeeRecipientSize, - LogsBloomSize, - ExtraDataSize, - DepositDataSize, - PublicKeySize, - SignatureSize, - ProofSize, - ProposerSlashingSize, - AttesterSlashingSize, - VoluntaryExitSize, - AttestationSize, - ValidatorCommitteeSize, - SyncCommitteeSize -))] -#[codec(mel_bound())] -pub struct HeaderUpdate< - FeeRecipientSize: Get, - LogsBloomSize: Get, - ExtraDataSize: Get, - SignatureSize: Get, - ProofSize: Get, - SyncCommitteeSize: Get, -> { - pub beacon_header: BeaconHeader, - pub execution_header: ExecutionPayloadHeader, - pub execution_branch: BoundedVec, - pub sync_aggregate: SyncAggregate, - pub signature_slot: u64, - pub block_root_branch: BoundedVec, - pub block_root_branch_header_root: H256, -} - -#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct ForkData { - // 1 or 0 bit, indicates whether a sync committee participated in a vote - pub current_version: [u8; 4], - pub genesis_validators_root: [u8; 32], -} - -#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct SigningData { - pub object_root: Root, - pub domain: Domain, -} - -#[derive( - Default, - Encode, - Decode, - CloneNoBound, - PartialEqNoBound, - RuntimeDebugNoBound, - TypeInfo, - MaxEncodedLen, -)] -pub struct ExecutionHeader { - pub parent_hash: H256, - pub block_hash: H256, - pub block_number: u64, - pub fee_recipient: H160, - pub state_root: H256, - pub receipts_root: H256, -} - -#[derive(Debug, PartialEq)] -pub enum ConvertError { - FromExecutionPayloadToHeaderError, -} - -impl, LogsBloomSize: Get, ExtraDataSize: Get> - TryFrom> - for ExecutionHeader -{ - type Error = ConvertError; - - fn try_from( - execution_payload: ExecutionPayloadHeader, - ) -> Result { - let mut fee_recipient = [0u8; 20]; - let fee_slice = execution_payload.fee_recipient.as_slice(); - if fee_slice.len() == 20 { - fee_recipient[0..20].copy_from_slice(&(fee_slice)); - } else { - return Err(ConvertError::FromExecutionPayloadToHeaderError) - } - Ok(ExecutionHeader { - parent_hash: execution_payload.parent_hash, - block_hash: execution_payload.block_hash, - block_number: execution_payload.block_number, - fee_recipient: H160::from(fee_recipient), - state_root: execution_payload.state_root, - receipts_root: execution_payload.receipts_root, - }) - } -} - -/// Sync committee as it is stored in the runtime storage. -#[derive( - Encode, Decode, PartialEqNoBound, CloneNoBound, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(SyncCommitteeSize))] -#[codec(mel_bound())] -pub struct SyncCommittee> { - pub pubkeys: BoundedVec, - pub aggregate_pubkey: PublicKey, -} - -/// Beacon block header as it is stored in the runtime storage. The block root is the -/// Merklization of a BeaconHeader. -#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -pub struct BeaconHeader { - // The slot for which this block is created. Must be greater than the slot of the block defined - // by parentRoot. - pub slot: u64, - // The index of the validator that proposed the block. - pub proposer_index: ValidatorIndex, - // The block root of the parent block, forming a block chain. - pub parent_root: Root, - // The hash root of the post state of running the state transition through this block. - pub state_root: Root, - // The hash root of the beacon block body - pub body_root: Root, -} - -#[derive( - Default, - Encode, - Decode, - CloneNoBound, - PartialEqNoBound, - RuntimeDebugNoBound, - TypeInfo, - MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(SyncCommitteeSize, SignatureSize))] -#[codec(mel_bound())] -pub struct SyncAggregate, SignatureSize: Get> { - #[cfg_attr(feature = "std", serde(deserialize_with = "from_hex_to_bytes"))] - pub sync_committee_bits: BoundedVec, - #[cfg_attr(feature = "std", serde(deserialize_with = "from_hex_to_bytes"))] - pub sync_committee_signature: BoundedVec, -} - -#[derive( - Default, - Encode, - Decode, - CloneNoBound, - PartialEqNoBound, - RuntimeDebugNoBound, - TypeInfo, - MaxEncodedLen, -)] -#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] -#[cfg_attr( - feature = "std", - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -#[scale_info(skip_type_params(FeeRecipientSize, LogsBloomSize, ExtraDataSize))] -#[codec(mel_bound())] -pub struct ExecutionPayloadHeader< - FeeRecipientSize: Get, - LogsBloomSize: Get, - ExtraDataSize: Get, -> { - pub parent_hash: H256, - #[cfg_attr(feature = "std", serde(deserialize_with = "from_hex_to_bytes"))] - pub fee_recipient: BoundedVec, - pub state_root: H256, - pub receipts_root: H256, - #[cfg_attr(feature = "std", serde(deserialize_with = "from_hex_to_bytes"))] - pub logs_bloom: BoundedVec, - pub prev_randao: H256, - pub block_number: u64, - pub gas_limit: u64, - pub gas_used: u64, - pub timestamp: u64, - #[cfg_attr(feature = "std", serde(deserialize_with = "from_hex_to_bytes"))] - pub extra_data: BoundedVec, - #[cfg_attr(feature = "std", serde(deserialize_with = "from_int_to_u256"))] - pub base_fee_per_gas: U256, - pub block_hash: H256, - pub transactions_root: H256, - pub withdrawals_root: H256, -} - -impl ExecutionHeader { - // Copied from ethereum_snowbridge::header - pub fn check_receipt_proof( - &self, - proof: &[Vec], - ) -> Option> { - match self.apply_merkle_proof(proof) { - Some((root, data)) if root == self.receipts_root => Some(rlp::decode(&data)), - Some((_, _)) => None, - None => None, - } - } - - // Copied from ethereum_snowbridge::header - pub fn apply_merkle_proof(&self, proof: &[Vec]) -> Option<(H256, Vec)> { - let mut iter = proof.into_iter().rev(); - let first_bytes = match iter.next() { - Some(b) => b, - None => return None, - }; - let item_to_prove: mpt::ShortNode = rlp::decode(first_bytes).ok()?; - - let final_hash: Option<[u8; 32]> = - iter.fold(Some(keccak_256(first_bytes)), |maybe_hash, bytes| { - let expected_hash = maybe_hash?; - let node: Box = bytes.as_slice().try_into().ok()?; - if (*node).contains_hash(expected_hash.into()) { - return Some(keccak_256(bytes)) - } - None - }); - - final_hash.map(|hash| (hash.into(), item_to_prove.value)) - } -} - -#[cfg(feature = "std")] -fn from_hex_to_bytes<'de, D, S>(deserializer: D) -> Result, D::Error> -where - D: Deserializer<'de>, - S: Get, -{ - let s = String::deserialize(deserializer)?; - - let str_without_0x = match s.strip_prefix("0x") { - Some(val) => val, - None => &s, - }; - - let hex_bytes = match hex::decode(str_without_0x) { - Ok(bytes) => bytes, - Err(e) => return Err(Error::custom(e.to_string())), - }; - - match BoundedVec::try_from(hex_bytes) { - Ok(bounded) => return Ok(bounded), - Err(_) => return Err(Error::custom("unable to create bounded vec")), - }; -} - -#[cfg(feature = "std")] -fn from_int_to_u256<'de, D>(deserializer: D) -> Result -where - D: Deserializer<'de>, -{ - let number = u128::deserialize(deserializer)?; - - Ok(U256::from(number)) -} +pub mod bits; +pub mod config; +pub mod merkle_proof; +pub mod receipt; +pub mod ssz; +pub mod types; +pub mod updates; + +#[cfg(feature = "std")] +mod serde_utils; + +pub use types::{ + BeaconHeader, CompactExecutionHeader, ExecutionHeaderState, ExecutionPayloadHeader, + FinalizedHeaderState, Fork, ForkData, ForkVersion, ForkVersions, PublicKey, Signature, + SigningData, SyncAggregate, SyncCommittee, +}; +pub use updates::{FinalizedHeaderUpdate, HeaderUpdate, InitialUpdate, SyncCommitteeUpdate}; + +pub use bits::decompress_sync_committee_bits; +pub use merkle_proof::verify_merkle_proof; +pub use receipt::verify_receipt_proof; diff --git a/parachain/primitives/beacon/src/merkle_proof.rs b/parachain/primitives/beacon/src/merkle_proof.rs new file mode 100644 index 000000000..0c794b27c --- /dev/null +++ b/parachain/primitives/beacon/src/merkle_proof.rs @@ -0,0 +1,23 @@ +use sp_core::H256; +use sp_io::hashing::sha2_256; + +// Reference https://github.com/ethereum/consensus-specs/blob/dev/ssz/merkle-proofs.md +// p.s. index here is actually [subtree_index](https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#get_subtree_index) +pub fn verify_merkle_proof(leaf: H256, branch: &[H256], index: u64, root: H256) -> bool { + let mut value: [u8; 32] = leaf.into(); + for (i, node) in branch.iter().enumerate() { + let mut data = [0u8; 64]; + if (index / (2u32.pow(i as u32) as u64) % 2) == 0 { + // left node + data[0..32].copy_from_slice(&value); + data[32..64].copy_from_slice(&node.0); + value = sha2_256(&data); + } else { + // right node + data[0..32].copy_from_slice(&node.0); + data[32..64].copy_from_slice(&value); + value = sha2_256(&data); + } + } + value == root.0 +} diff --git a/parachain/primitives/beacon/src/receipt.rs b/parachain/primitives/beacon/src/receipt.rs new file mode 100644 index 000000000..812ca5ee9 --- /dev/null +++ b/parachain/primitives/beacon/src/receipt.rs @@ -0,0 +1,37 @@ +use sp_core::H256; +use sp_io::hashing::keccak_256; +use sp_std::prelude::*; + +use snowbridge_ethereum::{mpt, Receipt}; + +pub fn verify_receipt_proof( + receipts_root: H256, + proof: &[Vec], +) -> Option> { + match apply_merkle_proof(proof) { + Some((root, data)) if root == receipts_root => Some(rlp::decode(&data)), + Some((_, _)) => None, + None => None, + } +} + +fn apply_merkle_proof(proof: &[Vec]) -> Option<(H256, Vec)> { + let mut iter = proof.iter().rev(); + let first_bytes = match iter.next() { + Some(b) => b, + None => return None, + }; + let item_to_prove: mpt::ShortNode = rlp::decode(first_bytes).ok()?; + + let final_hash: Option<[u8; 32]> = + iter.fold(Some(keccak_256(first_bytes)), |maybe_hash, bytes| { + let expected_hash = maybe_hash?; + let node: Box = bytes.as_slice().try_into().ok()?; + if (*node).contains_hash(expected_hash.into()) { + return Some(keccak_256(bytes)) + } + None + }); + + final_hash.map(|hash| (hash.into(), item_to_prove.value)) +} diff --git a/parachain/primitives/beacon/src/serde_utils.rs b/parachain/primitives/beacon/src/serde_utils.rs new file mode 100644 index 000000000..037987357 --- /dev/null +++ b/parachain/primitives/beacon/src/serde_utils.rs @@ -0,0 +1,128 @@ +use sp_core::U256; + +use core::fmt::Formatter; +use serde::{Deserialize, Deserializer}; + +// helper to deserialize arbitrary arrays like [T; N] +pub mod arrays { + use std::{convert::TryInto, marker::PhantomData}; + + use serde::{ + de::{SeqAccess, Visitor}, + ser::SerializeTuple, + Deserialize, Deserializer, Serialize, Serializer, + }; + + pub fn serialize( + data: &[T; N], + ser: S, + ) -> Result { + let mut s = ser.serialize_tuple(N)?; + for item in data { + s.serialize_element(item)?; + } + s.end() + } + + struct ArrayVisitor(PhantomData); + + impl<'de, T, const N: usize> Visitor<'de> for ArrayVisitor + where + T: Deserialize<'de>, + { + type Value = [T; N]; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str(&format!("an array of length {}", N)) + } + + #[inline] + fn visit_seq(self, mut seq: A) -> Result + where + A: SeqAccess<'de>, + { + // can be optimized using MaybeUninit + let mut data = Vec::with_capacity(N); + for _ in 0..N { + match (seq.next_element())? { + Some(val) => data.push(val), + None => return Err(serde::de::Error::invalid_length(N, &self)), + } + } + match data.try_into() { + Ok(arr) => Ok(arr), + Err(_) => unreachable!(), + } + } + } + + pub fn deserialize<'de, D, T, const N: usize>(deserializer: D) -> Result<[T; N], D::Error> + where + D: Deserializer<'de>, + T: Deserialize<'de>, + { + deserializer.deserialize_tuple(N, ArrayVisitor::(PhantomData)) + } +} + +pub(crate) fn from_hex_to_bytes<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let s = String::deserialize(deserializer)?; + + let str_without_0x = match s.strip_prefix("0x") { + Some(val) => val, + None => &s, + }; + + let hex_bytes = match hex::decode(str_without_0x) { + Ok(bytes) => bytes, + Err(e) => return Err(serde::de::Error::custom(e.to_string())), + }; + + Ok(hex_bytes) +} + +pub(crate) fn from_int_to_u256<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ + let number = u128::deserialize(deserializer)?; + + Ok(U256::from(number)) +} + +pub struct HexVisitor(); + +impl<'de, const LENGTH: usize> serde::de::Visitor<'de> for HexVisitor { + type Value = [u8; LENGTH]; + + fn expecting(&self, formatter: &mut Formatter) -> sp_std::fmt::Result { + formatter.write_str("a hex string with an '0x' prefix") + } + + fn visit_str(self, v: &str) -> Result + where + E: serde::de::Error, + { + let stripped = match v.strip_prefix("0x") { + Some(stripped) => stripped, + None => v, + }; + + let decoded = match hex::decode(stripped) { + Ok(decoded) => decoded, + Err(e) => return Err(serde::de::Error::custom(e.to_string())), + }; + if decoded.len() != LENGTH { + return Err(serde::de::Error::custom("publickey expected to be 48 characters")) + } + + let data: Self::Value = decoded + .try_into() + .map_err(|_e| serde::de::Error::custom("hex data has unexpected length"))?; + + Ok(data) + } +} diff --git a/parachain/primitives/beacon/src/ssz.rs b/parachain/primitives/beacon/src/ssz.rs new file mode 100644 index 000000000..68f1b3bcd --- /dev/null +++ b/parachain/primitives/beacon/src/ssz.rs @@ -0,0 +1,175 @@ +use crate::{ + config::{EXTRA_DATA_SIZE, FEE_RECIPIENT_SIZE, LOGS_BLOOM_SIZE, PUBKEY_SIZE, SIGNATURE_SIZE}, + types::{ + BeaconHeader, ExecutionPayloadHeader, ForkData, SigningData, SyncAggregate, SyncCommittee, + }, +}; +use byte_slice_cast::AsByteSlice; +use sp_core::H256; +use sp_std::{vec, vec::Vec}; +use ssz_rs::{ + prelude::{List, Vector}, + Bitvector, Deserialize, MerkleizationError, SimpleSerialize, Sized, U256, +}; +use ssz_rs_derive::SimpleSerialize as SimpleSerializeDerive; + +#[derive(Default, SimpleSerializeDerive, Clone, Debug)] +pub struct SSZBeaconBlockHeader { + pub slot: u64, + pub proposer_index: u64, + pub parent_root: [u8; 32], + pub state_root: [u8; 32], + pub body_root: [u8; 32], +} + +impl From for SSZBeaconBlockHeader { + fn from(beacon_header: BeaconHeader) -> Self { + SSZBeaconBlockHeader { + slot: beacon_header.slot, + proposer_index: beacon_header.proposer_index, + parent_root: beacon_header.parent_root.to_fixed_bytes(), + state_root: beacon_header.state_root.to_fixed_bytes(), + body_root: beacon_header.body_root.to_fixed_bytes(), + } + } +} + +#[derive(Default, SimpleSerializeDerive, Clone)] +pub struct SSZSyncCommittee { + pub pubkeys: Vector, COMMITTEE_SIZE>, + pub aggregate_pubkey: Vector, +} + +impl From> + for SSZSyncCommittee +{ + fn from(sync_committee: SyncCommittee) -> Self { + let mut pubkeys_vec = Vec::new(); + + for pubkey in sync_committee.pubkeys.iter() { + let conv_pubkey = Vector::::from_iter(pubkey.0); + + pubkeys_vec.push(conv_pubkey); + } + + let pubkeys = + Vector::, { COMMITTEE_SIZE }>::from_iter(pubkeys_vec.clone()); + + let aggregate_pubkey = + Vector::::from_iter(sync_committee.aggregate_pubkey.0); + + SSZSyncCommittee { pubkeys, aggregate_pubkey } + } +} + +#[derive(Default, Debug, SimpleSerializeDerive, Clone)] +pub struct SSZSyncAggregate { + pub sync_committee_bits: Bitvector, + pub sync_committee_signature: Vector, +} + +impl + From> for SSZSyncAggregate +{ + fn from(sync_aggregate: SyncAggregate) -> Self { + SSZSyncAggregate { + sync_committee_bits: Bitvector::::deserialize( + &sync_aggregate.sync_committee_bits, + ) + .expect("checked statically; qed"), + sync_committee_signature: Vector::::from_iter( + sync_aggregate.sync_committee_signature.0, + ), + } + } +} + +#[derive(Default, SimpleSerializeDerive, Clone)] +pub struct SSZForkData { + pub current_version: [u8; 4], + pub genesis_validators_root: [u8; 32], +} + +impl From for SSZForkData { + fn from(fork_data: ForkData) -> Self { + SSZForkData { + current_version: fork_data.current_version, + genesis_validators_root: fork_data.genesis_validators_root, + } + } +} + +#[derive(Default, SimpleSerializeDerive, Clone)] +pub struct SSZSigningData { + pub object_root: [u8; 32], + pub domain: [u8; 32], +} + +impl From for SSZSigningData { + fn from(signing_data: SigningData) -> Self { + SSZSigningData { + object_root: signing_data.object_root.into(), + domain: signing_data.domain.into(), + } + } +} + +#[derive(Default, SimpleSerializeDerive, Clone, Debug)] +pub struct SSZExecutionPayloadHeader { + pub parent_hash: [u8; 32], + pub fee_recipient: Vector, + pub state_root: [u8; 32], + pub receipts_root: [u8; 32], + pub logs_bloom: Vector, + pub prev_randao: [u8; 32], + pub block_number: u64, + pub gas_limit: u64, + pub gas_used: u64, + pub timestamp: u64, + pub extra_data: List, + pub base_fee_per_gas: U256, + pub block_hash: [u8; 32], + pub transactions_root: [u8; 32], + pub withdrawals_root: [u8; 32], +} + +impl From for SSZExecutionPayloadHeader { + fn from(payload: ExecutionPayloadHeader) -> Self { + SSZExecutionPayloadHeader { + parent_hash: payload.parent_hash.to_fixed_bytes(), + fee_recipient: Vector::::from_iter( + payload.fee_recipient.to_fixed_bytes(), + ), + state_root: payload.state_root.to_fixed_bytes(), + receipts_root: payload.receipts_root.to_fixed_bytes(), + logs_bloom: Vector::::from_iter(payload.logs_bloom), + prev_randao: payload.prev_randao.to_fixed_bytes(), + block_number: payload.block_number, + gas_limit: payload.gas_limit, + gas_used: payload.gas_used, + timestamp: payload.timestamp, + extra_data: List::::from_iter(payload.extra_data), + base_fee_per_gas: U256::from_bytes_le( + payload + .base_fee_per_gas + .as_byte_slice() + .try_into() + .expect("checked in prep; qed"), + ), + block_hash: payload.block_hash.to_fixed_bytes(), + transactions_root: payload.transactions_root.to_fixed_bytes(), + withdrawals_root: payload.withdrawals_root.to_fixed_bytes(), + } + } +} + +pub fn hash_tree_root(mut object: T) -> Result { + match object.hash_tree_root() { + Ok(node) => { + let fixed_bytes: [u8; 32] = + node.as_bytes().try_into().expect("Node is a newtype over [u8; 32]; qed"); + Ok(fixed_bytes.into()) + }, + Err(err) => Err(err), + } +} diff --git a/parachain/primitives/beacon/src/types.rs b/parachain/primitives/beacon/src/types.rs new file mode 100644 index 000000000..8ed1531d3 --- /dev/null +++ b/parachain/primitives/beacon/src/types.rs @@ -0,0 +1,449 @@ +use codec::{Decode, Encode, MaxEncodedLen}; +use frame_support::{CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; +use scale_info::TypeInfo; +use sp_core::{H160, H256, U256}; +use sp_runtime::RuntimeDebug; +use sp_std::prelude::*; + +use crate::config::{PUBKEY_SIZE, SIGNATURE_SIZE}; + +#[cfg(feature = "std")] +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[cfg(feature = "std")] +use crate::serde_utils::HexVisitor; + +use crate::ssz::{ + hash_tree_root, SSZBeaconBlockHeader, SSZExecutionPayloadHeader, SSZForkData, SSZSigningData, + SSZSyncAggregate, SSZSyncCommittee, +}; +use ssz_rs::MerkleizationError; + +pub use crate::bits::decompress_sync_committee_bits; + +pub type ValidatorIndex = u64; +pub type ForkVersion = [u8; 4]; + +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub struct ForkVersions { + pub genesis: Fork, + pub altair: Fork, + pub bellatrix: Fork, + pub capella: Fork, +} + +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub struct Fork { + pub version: [u8; 4], + pub epoch: u64, +} + +#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub struct PublicKey(pub [u8; PUBKEY_SIZE]); + +impl Default for PublicKey { + fn default() -> Self { + PublicKey([0u8; PUBKEY_SIZE]) + } +} + +impl From<[u8; PUBKEY_SIZE]> for PublicKey { + fn from(v: [u8; PUBKEY_SIZE]) -> Self { + Self(v) + } +} + +impl MaxEncodedLen for PublicKey { + fn max_encoded_len() -> usize { + PUBKEY_SIZE + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for PublicKey { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(HexVisitor::()).map(|v| v.into()) + } +} + +#[cfg(feature = "std")] +impl Serialize for PublicKey { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_bytes(&self.0) + } +} + +#[derive(Copy, Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +pub struct Signature(pub [u8; SIGNATURE_SIZE]); + +impl Default for Signature { + fn default() -> Self { + Signature([0u8; SIGNATURE_SIZE]) + } +} + +impl From<[u8; SIGNATURE_SIZE]> for Signature { + fn from(v: [u8; SIGNATURE_SIZE]) -> Self { + Self(v) + } +} + +#[cfg(feature = "std")] +impl<'de> Deserialize<'de> for Signature { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + deserializer.deserialize_str(HexVisitor::()).map(|v| v.into()) + } +} + +#[derive(Default, Encode, Decode, TypeInfo, MaxEncodedLen)] +pub struct ExecutionHeaderState { + pub beacon_block_root: H256, + pub beacon_slot: u64, + pub block_hash: H256, + pub block_number: u64, +} + +#[derive(Default, Encode, Decode, TypeInfo, MaxEncodedLen)] +pub struct FinalizedHeaderState { + pub beacon_block_root: H256, + pub beacon_slot: u64, + pub import_time: u64, +} + +#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug)] +pub struct ForkData { + // 1 or 0 bit, indicates whether a sync committee participated in a vote + pub current_version: [u8; 4], + pub genesis_validators_root: [u8; 32], +} + +impl ForkData { + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::(self.clone().into()) + } +} + +#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug)] +pub struct SigningData { + pub object_root: H256, + pub domain: H256, +} + +impl SigningData { + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::(self.clone().into()) + } +} + +/// Sync committee as it is stored in the runtime storage. +#[derive( + Encode, Decode, PartialEqNoBound, CloneNoBound, RuntimeDebugNoBound, TypeInfo, MaxEncodedLen, +)] +#[cfg_attr( + feature = "std", + derive(Serialize, Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[scale_info(skip_type_params(SyncCommitteeSize))] +#[codec(mel_bound())] +pub struct SyncCommittee { + #[cfg_attr(feature = "std", serde(with = "crate::serde_utils::arrays"))] + pub pubkeys: [PublicKey; COMMITTEE_SIZE], + pub aggregate_pubkey: PublicKey, +} + +impl Default for SyncCommittee { + fn default() -> Self { + SyncCommittee { + pubkeys: [Default::default(); COMMITTEE_SIZE], + aggregate_pubkey: Default::default(), + } + } +} + +impl SyncCommittee { + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::>(self.clone().into()) + } +} + +/// Beacon block header as it is stored in the runtime storage. The block root is the +/// Merklization of a BeaconHeader. +#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +#[cfg_attr(feature = "std", derive(Serialize, Deserialize))] +pub struct BeaconHeader { + // The slot for which this block is created. Must be greater than the slot of the block defined + // by parent root. + pub slot: u64, + // The index of the validator that proposed the block. + pub proposer_index: ValidatorIndex, + // The block root of the parent block, forming a block chain. + pub parent_root: H256, + // The hash root of the post state of running the state transition through this block. + pub state_root: H256, + // The hash root of the beacon block body + pub body_root: H256, +} + +impl BeaconHeader { + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::(self.clone().into()) + } +} + +#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] +#[cfg_attr( + feature = "std", + derive(Deserialize), + serde( + try_from = "IntermediateSyncAggregate", + deny_unknown_fields, + bound(serialize = ""), + bound(deserialize = "") + ) +)] +#[codec(mel_bound())] +pub struct SyncAggregate { + pub sync_committee_bits: [u8; COMMITTEE_BITS_SIZE], + pub sync_committee_signature: Signature, +} + +impl Default + for SyncAggregate +{ + fn default() -> Self { + SyncAggregate { + sync_committee_bits: [0; COMMITTEE_BITS_SIZE], + sync_committee_signature: Default::default(), + } + } +} + +impl + SyncAggregate +{ + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::>(self.clone().into()) + } +} + +// Serde deserialization helper for SyncAggregate +#[cfg(feature = "std")] +#[derive(Deserialize)] +struct IntermediateSyncAggregate { + #[cfg_attr(feature = "std", serde(deserialize_with = "crate::serde_utils::from_hex_to_bytes"))] + pub sync_committee_bits: Vec, + pub sync_committee_signature: Signature, +} + +#[cfg(feature = "std")] +impl + TryFrom for SyncAggregate +{ + type Error = String; + + fn try_from(other: IntermediateSyncAggregate) -> Result { + Ok(Self { + sync_committee_bits: other + .sync_committee_bits + .try_into() + .map_err(|_| "unexpected length".to_owned())?, + sync_committee_signature: other.sync_committee_signature, + }) + } +} + +// ExecutionPayloadHeader +// https://github.com/ethereum/annotated-spec/blob/master/capella/beacon-chain.md#executionpayloadheader +#[derive( + Default, Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, +)] +#[cfg_attr( + feature = "std", + derive(Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[codec(mel_bound())] +pub struct ExecutionPayloadHeader { + pub parent_hash: H256, + pub fee_recipient: H160, + pub state_root: H256, + pub receipts_root: H256, + #[cfg_attr(feature = "std", serde(deserialize_with = "crate::serde_utils::from_hex_to_bytes"))] + pub logs_bloom: Vec, + pub prev_randao: H256, + pub block_number: u64, + pub gas_limit: u64, + pub gas_used: u64, + pub timestamp: u64, + #[cfg_attr(feature = "std", serde(deserialize_with = "crate::serde_utils::from_hex_to_bytes"))] + pub extra_data: Vec, + #[cfg_attr(feature = "std", serde(deserialize_with = "crate::serde_utils::from_int_to_u256"))] + pub base_fee_per_gas: U256, + pub block_hash: H256, + pub transactions_root: H256, + pub withdrawals_root: H256, +} + +impl ExecutionPayloadHeader { + pub fn hash_tree_root(&self) -> Result { + hash_tree_root::(self.clone().into()) + } +} + +#[derive( + Default, + Encode, + Decode, + CloneNoBound, + PartialEqNoBound, + RuntimeDebugNoBound, + TypeInfo, + MaxEncodedLen, +)] +pub struct CompactExecutionHeader { + pub parent_hash: H256, + #[codec(compact)] + pub block_number: u64, + pub state_root: H256, + pub receipts_root: H256, +} + +impl From for CompactExecutionHeader { + fn from(execution_payload: ExecutionPayloadHeader) -> Self { + Self { + parent_hash: execution_payload.parent_hash, + block_number: execution_payload.block_number, + state_root: execution_payload.state_root, + receipts_root: execution_payload.receipts_root, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use hex_literal::hex; + + #[test] + pub fn test_hash_beacon_header1() { + let hash_root = BeaconHeader { + slot: 3, + proposer_index: 2, + parent_root: hex!("796ea53efb534eab7777809cc5ee2d84e7f25024b9d0c4d7e5bcaab657e4bdbd") + .into(), + state_root: hex!("ba3ff080912be5c9c158b2e962c1b39a91bc0615762ba6fa2ecacafa94e9ae0a") + .into(), + body_root: hex!("a18d7fcefbb74a177c959160e0ee89c23546482154e6831237710414465dcae5") + .into(), + } + .hash_tree_root(); + + assert!(hash_root.is_ok()); + assert_eq!( + hash_root.unwrap(), + hex!("7d42595818709e805dd2fa710a2d2c1f62576ef1ab7273941ac9130fb94b91f7").into() + ); + } + + #[test] + pub fn test_hash_beacon_header2() { + let hash_root = BeaconHeader { + slot: 3476424, + proposer_index: 314905, + parent_root: hex!("c069d7b49cffd2b815b0fb8007eb9ca91202ea548df6f3db60000f29b2489f28") + .into(), + state_root: hex!("444d293e4533501ee508ad608783a7d677c3c566f001313e8a02ce08adf590a3") + .into(), + body_root: hex!("6508a0241047f21ba88f05d05b15534156ab6a6f8e029a9a5423da429834e04a") + .into(), + } + .hash_tree_root(); + + assert!(hash_root.is_ok()); + assert_eq!( + hash_root.unwrap(), + hex!("0aa41166ff01e58e111ac8c42309a738ab453cf8d7285ed8477b1c484acb123e").into() + ); + } + + #[test] + pub fn test_hash_fork_data() { + let hash_root = ForkData { + current_version: hex!("83f38a34").into(), + genesis_validators_root: hex!( + "22370bbbb358800f5711a10ea9845284272d8493bed0348cab87b8ab1e127930" + ) + .into(), + } + .hash_tree_root(); + + assert!(hash_root.is_ok()); + assert_eq!( + hash_root.unwrap(), + hex!("57c12c4246bc7152b174b51920506bf943eff9c7ffa50b9533708e9cc1f680fc").into() + ); + } + + #[test] + pub fn test_hash_signing_data() { + let hash_root = SigningData { + object_root: hex!("63654cbe64fc07853f1198c165dd3d49c54fc53bc417989bbcc66da15f850c54") + .into(), + domain: hex!("037da907d1c3a03c0091b2254e1480d9b1783476e228ab29adaaa8f133e08f7a").into(), + } + .hash_tree_root(); + + assert!(hash_root.is_ok()); + assert_eq!( + hash_root.unwrap(), + hex!("b9eb2caf2d691b183c2d57f322afe505c078cd08101324f61c3641714789a54e").into() + ); + } + + #[test] + pub fn test_hash_sync_aggregate() { + let hash_root = SyncAggregate::<512, 64>{ + sync_committee_bits: hex!("cefffffefffffff767fffbedffffeffffeeffdffffdebffffff7f7dbdf7fffdffffbffcfffdff79dfffbbfefff2ffffff7ddeff7ffffc98ff7fbfffffffffff7").into(), + sync_committee_signature: hex!("8af1a8577bba419fe054ee49b16ed28e081dda6d3ba41651634685e890992a0b675e20f8d9f2ec137fe9eb50e838aa6117f9f5410e2e1024c4b4f0e098e55144843ce90b7acde52fe7b94f2a1037342c951dc59f501c92acf7ed944cb6d2b5f7").into(), + }.hash_tree_root(); + + assert!(hash_root.is_ok()); + assert_eq!( + hash_root.unwrap(), + hex!("e6dcad4f60ce9ff8a587b110facbaf94721f06cd810b6d8bf6cffa641272808d").into() + ); + } + + #[test] + pub fn test_hash_execution_payload() { + let hash_root = + ExecutionPayloadHeader{ + parent_hash: hex!("eadee5ab098dde64e9fd02ae5858064bad67064070679625b09f8d82dec183f7").into(), + fee_recipient: hex!("f97e180c050e5ab072211ad2c213eb5aee4df134").into(), + state_root: hex!("564fa064c2a324c2b5978d7fdfc5d4224d4f421a45388af1ed405a399c845dff").into(), + receipts_root: hex!("56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421").into(), + logs_bloom: hex!("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").to_vec().try_into().expect("logs bloom is too long"), + prev_randao: hex!("6bf538bdfbdf1c96ff528726a40658a91d0bda0f1351448c4c4f3604db2a0ccf").into(), + block_number: 477434, + gas_limit: 8154925, + gas_used: 0, + timestamp: 1652816940, + extra_data: vec![].try_into().expect("extra data field is too long"), + base_fee_per_gas: U256::from(7 as i16), + block_hash: hex!("cd8df91b4503adb8f2f1c7a4f60e07a1f1a2cbdfa2a95bceba581f3ff65c1968").into(), + transactions_root: hex!("7ffe241ea60187fdb0187bfa22de35d1f9bed7ab061d9401fd47e34a54fbede1").into(), + withdrawals_root: hex!("28ba1834a3a7b657460ce79fa3a1d909ab8828fd557659d4d0554a9bdbc0ec30").into(), + }.hash_tree_root(); + assert!(hash_root.is_ok()); + } +} diff --git a/parachain/primitives/beacon/src/updates.rs b/parachain/primitives/beacon/src/updates.rs new file mode 100644 index 000000000..51f5a4b95 --- /dev/null +++ b/parachain/primitives/beacon/src/updates.rs @@ -0,0 +1,99 @@ +use codec::{Decode, Encode}; +use frame_support::{CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; +use scale_info::TypeInfo; +use sp_core::H256; +use sp_std::prelude::*; + +#[cfg(feature = "std")] +use serde::Deserialize; + +use crate::types::{BeaconHeader, ExecutionPayloadHeader, SyncAggregate, SyncCommittee}; + +#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] +#[cfg_attr( + feature = "std", + derive(serde::Serialize, serde::Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[scale_info(skip_type_params(SyncCommitteeSize))] +#[codec(mel_bound())] +pub struct InitialUpdate { + pub header: BeaconHeader, + pub current_sync_committee: SyncCommittee, + pub current_sync_committee_branch: Vec, + pub validators_root: H256, + pub import_time: u64, +} + +impl Default for InitialUpdate { + fn default() -> Self { + InitialUpdate { + header: Default::default(), + current_sync_committee: Default::default(), + current_sync_committee_branch: Default::default(), + validators_root: Default::default(), + import_time: Default::default(), + } + } +} + +#[derive( + Default, Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, +)] +#[cfg_attr( + feature = "std", + derive(serde::Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[scale_info(skip_type_params(SyncCommitteeSize))] +#[codec(mel_bound())] +pub struct SyncCommitteeUpdate { + pub attested_header: BeaconHeader, + pub next_sync_committee: SyncCommittee, + pub next_sync_committee_branch: Vec, + pub finalized_header: BeaconHeader, + pub finality_branch: Vec, + pub sync_aggregate: SyncAggregate, + pub sync_committee_period: u64, + pub signature_slot: u64, + pub block_roots_root: H256, + pub block_roots_branch: Vec, +} + +#[derive( + Default, Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo, +)] +#[cfg_attr( + feature = "std", + derive(serde::Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[scale_info(skip_type_params(SyncCommitteeSize,))] +#[codec(mel_bound())] +pub struct FinalizedHeaderUpdate { + pub attested_header: BeaconHeader, + pub finalized_header: BeaconHeader, + pub finality_branch: Vec, + pub sync_aggregate: SyncAggregate, + pub signature_slot: u64, + pub block_roots_root: H256, + pub block_roots_branch: Vec, +} + +#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] +#[cfg_attr( + feature = "std", + derive(Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +#[scale_info(skip_type_params(SyncCommitteeSize))] +#[codec(mel_bound())] +pub struct HeaderUpdate { + pub beacon_header: BeaconHeader, + pub execution_header: ExecutionPayloadHeader, + pub execution_branch: Vec, + pub sync_aggregate: SyncAggregate, + pub signature_slot: u64, + pub block_root_branch: Vec, + pub block_root_branch_header_root: H256, +} diff --git a/parachain/templates/beacon_benchmarking_data.rs.mustache b/parachain/templates/beacon_benchmarking_data.rs.mustache index c03bd4ecc..5f3260891 100644 --- a/parachain/templates/beacon_benchmarking_data.rs.mustache +++ b/parachain/templates/beacon_benchmarking_data.rs.mustache @@ -3,38 +3,38 @@ use frame_support::traits::Get; use hex_literal::hex; use snowbridge_beacon_primitives::{ - BeaconHeader, ExecutionPayloadHeaderCapella, FinalizedHeaderUpdate, HeaderUpdate, InitialSync, PublicKey, + BeaconHeader, ExecutionPayloadHeaderCapella, FinalizedHeaderUpdate, HeaderUpdate, InitialUpdate, PublicKey, SyncAggregate, SyncCommittee, SyncCommitteePeriodUpdate, }; use sp_core::U256; use sp_std::vec; pub fn initial_sync, ProofSize: Get>( - ) -> InitialSync { + ) -> InitialUpdate { let time_now = 1675679352; //2023.2.6 - return InitialSync{ + return InitialUpdate{ header: BeaconHeader{ - slot: {{InitialSync.Header.Slot}}, - proposer_index: {{InitialSync.Header.ProposerIndex}}, - parent_root: hex!("{{InitialSync.Header.ParentRoot}}").into(), - state_root: hex!("{{InitialSync.Header.StateRoot}}").into(), - body_root: hex!("{{InitialSync.Header.BodyRoot}}").into(), + slot: {{InitialUpdate.Header.Slot}}, + proposer_index: {{InitialUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{InitialUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{InitialUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{InitialUpdate.Header.BodyRoot}}").into(), }, current_sync_committee: SyncCommittee{ - pubkeys: vec![ - {{#InitialSync.CurrentSyncCommittee.Pubkeys}} - PublicKey(hex!("{{.}}").into()), - {{/InitialSync.CurrentSyncCommittee.Pubkeys}} - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("{{InitialSync.CurrentSyncCommittee.AggregatePubkey}}").into()) + pubkeys: [ + {{#InitialUpdate.CurrentSyncCommittee.Pubkeys}} + hex!("{{.}}").into(), + {{/InitialUpdate.CurrentSyncCommittee.Pubkeys}} + ], + aggregate_pubkey: hex!("{{InitialUpdate.CurrentSyncCommittee.AggregatePubkey}}").into(), }, current_sync_committee_branch: vec![ - {{#InitialSync.CurrentSyncCommitteeBranch}} + {{#InitialUpdate.CurrentSyncCommitteeBranch}} hex!("{{.}}").into(), - {{/InitialSync.CurrentSyncCommitteeBranch}} - ].try_into().expect("too many branch proof items"), - validators_root: hex!("{{InitialSync.ValidatorsRoot}}").into(), + {{/InitialUpdate.CurrentSyncCommitteeBranch}} + ], + validators_root: hex!("{{InitialUpdate.ValidatorsRoot}}").into(), import_time: time_now + 97200, // now + 27 hour sync committee period }; } @@ -55,16 +55,16 @@ pub fn sync_committee_update< next_sync_committee: SyncCommittee { pubkeys: vec![ {{#SyncCommitteeUpdate.NextSyncCommittee.Pubkeys}} - PublicKey(hex!("{{.}}").into()), + hex!("{{.}}").into(), {{/SyncCommitteeUpdate.NextSyncCommittee.Pubkeys}} - ].try_into().expect("too many pubkeys"), - aggregate_pubkey: PublicKey(hex!("{{SyncCommitteeUpdate.NextSyncCommittee.AggregatePubkey}}").into()) + ], + aggregate_pubkey: hex!("{{SyncCommitteeUpdate.NextSyncCommittee.AggregatePubkey}}").into(), }, next_sync_committee_branch: vec![ {{#SyncCommitteeUpdate.NextSyncCommitteeBranch}} hex!("{{.}}").into(), {{/SyncCommitteeUpdate.NextSyncCommitteeBranch}} - ].try_into().expect("too many branch proof items"), + ], finalized_header: BeaconHeader{ slot: {{SyncCommitteeUpdate.FinalizedHeader.Slot}}, proposer_index: {{SyncCommitteeUpdate.FinalizedHeader.ProposerIndex}}, @@ -76,10 +76,10 @@ pub fn sync_committee_update< {{#SyncCommitteeUpdate.FinalityBranch}} hex!("{{.}}").into(), {{/SyncCommitteeUpdate.FinalityBranch}} - ].try_into().expect("too many branch proof items"), + ], sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeBits}}").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeSignature}}").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeBits}}"), + sync_committee_signature: hex!("{{SyncCommitteeUpdate.SyncAggregate.SyncCommitteeSignature}}").into(), }, sync_committee_period: {{SyncCommitteeUpdate.SyncCommitteePeriod}}, signature_slot: {{SyncCommitteeUpdate.SignatureSlot}}, @@ -88,7 +88,7 @@ pub fn sync_committee_update< {{#SyncCommitteeUpdate.BlockRootBranch}} hex!("{{.}}").into(), {{/SyncCommitteeUpdate.BlockRootBranch}} - ].try_into().expect("too many branch proof items"), + ], }; } @@ -116,10 +116,10 @@ pub fn finalized_header_update< {{#FinalizedHeaderUpdate.FinalityBranch}} hex!("{{.}}").into(), {{/FinalizedHeaderUpdate.FinalityBranch}} - ].try_into().expect("too many branch proof items"), + ], sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeBits}}").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeSignature}}").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeBits}}"), + sync_committee_signature: hex!("{{FinalizedHeaderUpdate.SyncAggregate.SyncCommitteeSignature}}").into(), }, signature_slot: {{FinalizedHeaderUpdate.SignatureSlot}}, block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), @@ -127,7 +127,7 @@ pub fn finalized_header_update< {{#FinalizedHeaderUpdate.BlockRootBranch}} hex!("{{.}}").into(), {{/FinalizedHeaderUpdate.BlockRootBranch}} - ].try_into().expect("too many branch proof items") + ] }; } @@ -156,16 +156,16 @@ pub fn header_update< }, execution_header: ExecutionPayloadHeaderCapella{ parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.ParentHash}}").into(), - fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.FeeRecipient}}").to_vec().try_into().expect("fee recipient too long"), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.FeeRecipient}}").into(), state_root: hex!("{{HeaderUpdate.ExecutionHeader.StateRoot}}").into(), receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.ReceiptsRoot}}").into(), - logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.LogsBloom}}").to_vec().try_into().expect("logs bloom too long"), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.LogsBloom}}").into(), prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.PrevRandao}}").into(), block_number: {{HeaderUpdate.ExecutionHeader.BlockNumber}}, gas_limit: {{HeaderUpdate.ExecutionHeader.GasLimit}}, gas_used: {{HeaderUpdate.ExecutionHeader.GasUsed}}, timestamp: {{HeaderUpdate.ExecutionHeader.Timestamp}}, - extra_data: hex!("{{HeaderUpdate.ExecutionHeader.ExtraData}}").to_vec().try_into().expect("extra data too long"), + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.ExtraData}}").into(), base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.BaseFeePerGas}} as u64), block_hash: hex!("{{HeaderUpdate.ExecutionHeader.BlockHash}}").into(), transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.TransactionRoot}}").into(), @@ -177,15 +177,15 @@ pub fn header_update< {{/HeaderUpdate.ExecutionBranch}} ].try_into().expect("too many branch proof items"), sync_aggregate: SyncAggregate{ - sync_committee_bits: hex!("{{HeaderUpdate.SyncAggregate.SyncCommitteeBits}}").to_vec().try_into().expect("too many sync committee bits"), - sync_committee_signature: hex!("{{HeaderUpdate.SyncAggregate.SyncCommitteeSignature}}").to_vec().try_into().expect("signature too long"), + sync_committee_bits: hex!("{{HeaderUpdate.SyncAggregate.SyncCommitteeBits}}"), + sync_committee_signature: hex!("{{HeaderUpdate.SyncAggregate.SyncCommitteeSignature}}").into(), }, signature_slot: {{HeaderUpdate.SignatureSlot}}, block_root_branch: vec![ {{#HeaderUpdate.BlockRootBranch}} hex!("{{.}}").into(), {{/HeaderUpdate.BlockRootBranch}} - ].try_into().expect("too many branch proof items"), + ], block_root_branch_header_root: hex!("{{HeaderUpdate.BlockRootBranchHeaderRoot}}").into(), }; } diff --git a/relayer/relays/beacon/header/syncer/api/api_response.go b/relayer/relays/beacon/header/syncer/api/api_response.go index be3bb9fe4..c874e4236 100644 --- a/relayer/relays/beacon/header/syncer/api/api_response.go +++ b/relayer/relays/beacon/header/syncer/api/api_response.go @@ -443,9 +443,12 @@ func (s SyncAggregateResponse) ToScale() (scale.SyncAggregate, error) { return scale.SyncAggregate{}, err } + var syncCommitteeSignature [96]byte + copy(syncCommitteeSignature[:], aggregateSignature) + return scale.SyncAggregate{ SyncCommitteeBits: bits, - SyncCommitteeSignature: aggregateSignature, + SyncCommitteeSignature: syncCommitteeSignature, }, nil } @@ -568,7 +571,7 @@ func (b BeaconBlockResponse) ToScale() (scale.BeaconBlock, error) { return scale.BeaconBlock{}, err } - feeRecipient, err := util.HexStringToByteArray(executionPayload.FeeRecipient) + feeRecipient, err := util.HexStringTo20Bytes(executionPayload.FeeRecipient) if err != nil { return scale.BeaconBlock{}, err } @@ -1383,7 +1386,7 @@ func CapellaExecutionPayloadToScale(e *state.ExecutionPayloadCapella, activeSpec return scale.ExecutionPayloadHeaderCapella{ ParentHash: types.NewH256(e.ParentHash[:]), - FeeRecipient: e.FeeRecipient[:], + FeeRecipient: e.FeeRecipient, StateRoot: types.NewH256(e.StateRoot[:]), ReceiptsRoot: types.NewH256(e.ReceiptsRoot[:]), LogsBloom: e.LogsBloom[:], @@ -1404,6 +1407,6 @@ func SyncAggregateToScale(s state.SyncAggregate) scale.SyncAggregate { aggregateSignature := s.GetSyncAggregateSignature() return scale.SyncAggregate{ SyncCommitteeBits: s.GetSyncAggregateBits(), - SyncCommitteeSignature: aggregateSignature[:], + SyncCommitteeSignature: aggregateSignature, } } diff --git a/relayer/relays/beacon/header/syncer/scale/beacon_scale.go b/relayer/relays/beacon/header/syncer/scale/beacon_scale.go index 5eeccea35..7db3f0a9d 100644 --- a/relayer/relays/beacon/header/syncer/scale/beacon_scale.go +++ b/relayer/relays/beacon/header/syncer/scale/beacon_scale.go @@ -1,8 +1,11 @@ package scale import ( + "fmt" + "github.com/ethereum/go-ethereum/common" ssz "github.com/ferranbt/fastssz" + "github.com/snowfork/go-substrate-rpc-client/v4/scale" "github.com/snowfork/go-substrate-rpc-client/v4/types" "github.com/snowfork/snowbridge/relayer/relays/beacon/state" ) @@ -165,7 +168,7 @@ type SignedBLSToExecutionChange struct { type ExecutionPayloadHeaderCapella struct { ParentHash types.H256 - FeeRecipient []byte + FeeRecipient types.H160 StateRoot types.H256 ReceiptsRoot types.H256 LogsBloom []byte @@ -229,9 +232,49 @@ type SyncCommittee struct { AggregatePubkey [48]byte } +// Use a custom SCALE encoder to encode SyncCommitteeBits as fixed array +func (s SyncCommittee) Encode(encoder scale.Encoder) error { + + switch len(s.Pubkeys) { + case 32: + var pubkeys [32][48]byte + copy(pubkeys[:], s.Pubkeys) + encoder.Encode(pubkeys) + case 512: + var pubkeys [512][48]byte + copy(pubkeys[:], s.Pubkeys) + encoder.Encode(pubkeys) + default: + return fmt.Errorf("invalid sync committee size") + } + encoder.Encode(s.AggregatePubkey) + return nil +} + type SyncAggregate struct { SyncCommitteeBits []byte - SyncCommitteeSignature []byte + SyncCommitteeSignature [96]byte +} + +// Use a custom SCALE encoder to encode SyncCommitteeBits as fixed array +func (s SyncAggregate) Encode(encoder scale.Encoder) error { + + switch len(s.SyncCommitteeBits) { + case 4: + // 32 / 8 = 4 + var syncCommitteeBits [4]byte + copy(syncCommitteeBits[:], s.SyncCommitteeBits) + encoder.Encode(syncCommitteeBits) + case 64: + // 512 / 8 = 64 + var syncCommitteeBits [64]byte + copy(syncCommitteeBits[:], s.SyncCommitteeBits) + encoder.Encode(syncCommitteeBits) + default: + return fmt.Errorf("invalid sync committee size") + } + encoder.Encode(s.SyncCommitteeSignature) + return nil } func (b *BeaconHeader) ToSSZ() *state.BeaconBlockHeader { diff --git a/relayer/relays/beacon/header/syncer/scale/json_conversion.go b/relayer/relays/beacon/header/syncer/scale/json_conversion.go index 6e6522765..af50f2430 100644 --- a/relayer/relays/beacon/header/syncer/scale/json_conversion.go +++ b/relayer/relays/beacon/header/syncer/scale/json_conversion.go @@ -67,7 +67,7 @@ func (b *BeaconHeader) ToJSON() json.BeaconHeader { func (e *ExecutionPayloadHeaderCapella) ToJSON() json.ExecutionPayloadHeaderCapella { return json.ExecutionPayloadHeaderCapella{ ParentHash: e.ParentHash.Hex(), - FeeRecipient: util.BytesToHexString(e.FeeRecipient), + FeeRecipient: util.BytesToHexString(e.FeeRecipient[:]), StateRoot: e.StateRoot.Hex(), ReceiptsRoot: e.ReceiptsRoot.Hex(), LogsBloom: util.BytesToHexString(e.LogsBloom), @@ -99,7 +99,7 @@ func (s *SyncCommittee) ToJSON() json.SyncCommittee { func (s *SyncAggregate) ToJSON() json.SyncAggregate { return json.SyncAggregate{ SyncCommitteeBits: util.BytesToHexString(s.SyncCommitteeBits), - SyncCommitteeSignature: util.BytesToHexString(s.SyncCommitteeSignature), + SyncCommitteeSignature: util.BytesToHexString(s.SyncCommitteeSignature[:]), } }