From 4c850e8b14e2cbf94a5c94ef5c6b782e0d5c8141 Mon Sep 17 00:00:00 2001 From: Ron Date: Wed, 20 Mar 2024 16:08:01 +0800 Subject: [PATCH] Inline execution update into proof of inbound message & Remove execution header storage (#125) * Remove execution header storage & submit inbound message with execution update * Fix ci breaking * More refactoring * Update beacon test fixtures * Format code * Initialize storage with finalized checkpoint for benchmark * Update weights include verify the execution proof * Fix breaking test * Remove fixture not in use * Add detail for InvalidExecutionProof * Initialize checkpoint for tests on demand * Revert error as NotBootstrapped for submit_update_with_missing_bootstrap * Add verify_execution_header tests back * Add error test back * Cleanup templates * Update bridges/snowbridge/primitives/beacon/src/types.rs Co-authored-by: Vincent Geddes * Narrowed inputs * Remove fields irrelevant from proof * Update bridges/snowbridge/primitives/core/src/inbound.rs Co-authored-by: Vincent Geddes * Update bridges/snowbridge/pallets/ethereum-client/src/impls.rs Co-authored-by: Vincent Geddes * Polish --------- Co-authored-by: Vincent Geddes --- .../ethereum-client/fixtures/src/lib.rs | 274 +++++++++----- .../ethereum-client/src/benchmarking/mod.rs | 18 - .../pallets/ethereum-client/src/impls.rs | 138 +++++-- .../pallets/ethereum-client/src/lib.rs | 181 +-------- .../pallets/ethereum-client/src/mock.rs | 59 +-- .../pallets/ethereum-client/src/tests.rs | 357 ++++++------------ .../pallets/ethereum-client/src/types.rs | 12 +- .../pallets/ethereum-client/src/weights.rs | 7 - .../fixtures/execution-header-update.json | 54 --- .../tests/fixtures/execution-proof.json | 54 +++ .../fixtures/finalized-header-update.json | 48 +-- .../tests/fixtures/inbound-message.json | 94 +++-- .../tests/fixtures/initial-checkpoint.json | 30 +- .../tests/fixtures/sync-committee-update.json | 42 ++- .../pallets/inbound-queue/fixtures/src/lib.rs | 11 - .../fixtures/src/register_token.rs | 84 ++++- .../register_token_with_insufficient_fee.rs | 42 --- .../inbound-queue/fixtures/src/send_token.rs | 82 +++- .../fixtures/src/send_token_to_penpal.rs | 86 ++++- .../inbound-queue/src/benchmarking/mod.rs | 4 +- .../pallets/inbound-queue/src/lib.rs | 8 +- .../pallets/inbound-queue/src/mock.rs | 35 +- .../pallets/inbound-queue/src/test.rs | 40 +- .../snowbridge/primitives/beacon/src/lib.rs | 8 +- .../snowbridge/primitives/beacon/src/types.rs | 100 ++--- .../primitives/beacon/src/updates.rs | 32 +- .../snowbridge/primitives/core/src/inbound.rs | 18 +- .../snowbridge/runtime/test-common/src/lib.rs | 22 -- ...ures.mustache => beacon-fixtures.mustache} | 109 +++++- .../templates/inbound-fixtures.mustache | 95 +++++ .../templates/register_token.mustache | 45 --- .../snowbridge/templates/send_token.mustache | 45 --- .../bridge-hub-rococo/src/tests/snowbridge.rs | 144 +++---- .../bridge-hubs/bridge-hub-rococo/src/lib.rs | 6 +- .../snowbridge_pallet_ethereum_client.rs | 22 -- .../snowbridge_pallet_inbound_queue.rs | 14 +- 36 files changed, 1224 insertions(+), 1196 deletions(-) delete mode 100755 bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-header-update.json create mode 100755 bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-proof.json delete mode 100644 bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token_with_insufficient_fee.rs rename bridges/snowbridge/templates/{benchmarking-fixtures.mustache => beacon-fixtures.mustache} (60%) create mode 100644 bridges/snowbridge/templates/inbound-fixtures.mustache delete mode 100644 bridges/snowbridge/templates/register_token.mustache delete mode 100644 bridges/snowbridge/templates/send_token.mustache diff --git a/bridges/snowbridge/pallets/ethereum-client/fixtures/src/lib.rs b/bridges/snowbridge/pallets/ethereum-client/fixtures/src/lib.rs index d487ae1712c6..37fe45ba60b0 100644 --- a/bridges/snowbridge/pallets/ethereum-client/fixtures/src/lib.rs +++ b/bridges/snowbridge/pallets/ethereum-client/fixtures/src/lib.rs @@ -6,9 +6,10 @@ use hex_literal::hex; use snowbridge_beacon_primitives::{ - types::deneb, updates::AncestryProof, BeaconHeader, ExecutionHeaderUpdate, - NextSyncCommitteeUpdate, SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader, + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, NextSyncCommitteeUpdate, + SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader, }; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; use sp_core::U256; use sp_std::{boxed::Box, vec}; @@ -20,11 +21,11 @@ type Update = snowbridge_beacon_primitives::Update; pub fn make_checkpoint() -> Box { Box::new(CheckpointUpdate { header: BeaconHeader { - slot: 2496, - proposer_index: 2, - parent_root: hex!("c99e49787106733eeebab4d93eb326e1f2214575c9d928f0c4ab0da0776f1622").into(), - state_root: hex!("fbf8a08c86ef36bd173e37e733da4a78aa8e85fee99a990e858dd12a59087fde").into(), - body_root: hex!("a2a8ad06901447b2807a9059580a4c40d8a941f325b1343c69f7c7c6c90e4ab0").into(), + slot: 864, + proposer_index: 4, + parent_root: hex!("614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614").into(), + state_root: hex!("5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a").into(), + body_root: hex!("0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e").into(), }, current_sync_committee: SyncCommittee { pubkeys: [ @@ -544,20 +545,20 @@ pub fn make_checkpoint() -> Box { aggregate_pubkey: hex!("8fbd66eeec2ff69ef0b836f04b1d67d88bcd4dfd495061964ad757c77abe822a39fa1cd8ed0d4d9bc9276cea73fd745c").into(), }, current_sync_committee_branch: vec![ - hex!("3ade38d498a062b50880a9409e1ca3a7fd4315d91eeb3bb83e56ac6bfe8d6a59").into(), - hex!("93880225bf99a0c5ec22b266ff829837754e9c5edf37a68c05b8f803fd82fa45").into(), - hex!("4c60656ec9a95fcf11030ad309c716b5b15beb7f60a0bcfc7c9d4eff505472ff").into(), - hex!("22d1645fceb4bf9a695043dda19a53e784ec70df6a6b1bd66ea30eba1cca5f2f").into(), - hex!("a8fc6cad84ceefc633ec56c2d031d525e1cb4b51c70eb252919fce5bba9a1fde").into(), + hex!("3ade38d498a062b50880a9409e1ca3a7fd4315d91eeb3bb83e56ac6bfe8d6a59").into(), + hex!("a9e90f89e7f90fd5d79a6bbcaf40ba5cfc05ab1b561ac51c84867c32248d5b1e").into(), + hex!("bd1a76b03e02402bb24a627de1980a80ab17691980271f597b844b89b497ef75").into(), + hex!("07bbcd27c7cad089023db046eda17e8209842b7d97add8b873519e84fe6480e7").into(), + hex!("94c11eeee4cb6192bf40810f23486d8c75dfbc2b6f28d988d6f74435ede243b0").into(), ], validators_root: hex!("270d43e74ce340de4bca2b1936beca0f4f5408d9e78aec4850920baf659d5b69").into(), - block_roots_root: hex!("d160b7687041891b73e54b06fc4e04f82d0fa8fdd76705895e216c6b24709dfe").into(), + block_roots_root: hex!("b9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10").into(), block_roots_branch: vec![ - hex!("105290e42d98ab6a0ada6e55453cede36c672abf645eeb986b88d7487616e135").into(), - hex!("9da41f274bcdf6122335443d9ce94d07163b48dba3e2f9499ff56f4e48b48b99").into(), - hex!("ecea7e1d3152d8130e83afdfe34b4de4ba2b69a33c9471991096daf454de9cf5").into(), - hex!("b2bf1758e50b2bfff29169fbc70fdb884b2b05bb615dbc53567574da6f4f1ae2").into(), - hex!("cd87069daf70975779126d6af833b7d636c75ca4d5e750ebcad0e76408a5e5bf").into(), + hex!("733422bd810895dab74cbbe07c69dd440cbb51f573181ad4dddac30fcdd0f41f").into(), + hex!("9b9eca73ab01d14549c325ba1b4610bb20bf1f8ec2dbd649f9d8cc7f3cea75fa").into(), + hex!("bcc666ad0ad9f9725cbd682bc95589d35b1b53b2a615f1e6e8dd5e086336becf").into(), + hex!("3069b547a08f703a1715016e926cbd64e71f93f64fb68d98d8c8f1ab745c46e5").into(), + hex!("c2de7e1097239404e17b263cfa0473533cc41e903cb03440d633bc5c27314cb4").into(), ], }) } @@ -567,13 +568,13 @@ pub fn make_sync_committee_update() -> Box { attested_header: BeaconHeader { slot: 129, proposer_index: 5, - parent_root: hex!("e32b6c18f029e755b0273dc1c4fa2bc4979794c8286ad40276c1b8a8e36049d8").into(), - state_root: hex!("5ec9dacf25a5f09f20be0c59246b3d8dcfe64bd085b4bac5cec180690339801e").into(), - body_root: hex!("4080cf2412d6ff77fc3164ad6155423a7112f207f173145ec16371a93f481f87").into(), + parent_root: hex!("c2def03fe44a2802130ca1a6d8406e4ccf4f344fec7075d4d84431cd4a8b0904").into(), + state_root: hex!("fa62cde6666add7353d7aedcb61ebe3c6c84b5361e34f814825b1250affb5be4").into(), + body_root: hex!("0f9c69f243fe7b5fa5860396c66c720a9e8b1e526e7914188930497cc4a9134c").into(), }, sync_aggregate: SyncAggregate{ sync_committee_bits: hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - sync_committee_signature: hex!("a761c3333fbb3d36bc8f65454f898da38001499dcd37494cf3d86940a995399ae649216ba4c985af154f83f72c8b1856079b7636a7a8d7d3f7602df2cbf699edb72b65253e82de4d9cc4db7377eafb22f799129f63f094a21c00675bdd5cc243").into(), + sync_committee_signature: hex!("810cfde2afea3e276256c09bdf1cd321c33dcadeefddcfd24f488e6f756d917cfda90b5b437b3a4b4ef880985afa28a40cf565ec0a82877ddee36adc01d55d9d4a911ae3e22556e4c2636f1c707366fba019fb49450440fcd263d0b054b04bf0").into(), }, signature_slot: 130, next_sync_committee_update: Some(NextSyncCommitteeUpdate { @@ -1096,34 +1097,34 @@ pub fn make_sync_committee_update() -> Box { }, next_sync_committee_branch: vec![ hex!("3ade38d498a062b50880a9409e1ca3a7fd4315d91eeb3bb83e56ac6bfe8d6a59").into(), - hex!("fd1e5ff5d4a15081efe3ff17857b1f95984c9a271b1c41c2f81f43e60c2cc541").into(), - hex!("e1c97f93bb7352d395d1ff8ee29881572cb7eb5d71634783701171dcd30cd93d").into(), - hex!("77fa2170ddbd89b15dae02f2e6cf9f76c8e00d1c4217320acffbe01576d0da61").into(), - hex!("e97288e0627219087a024078d69445f34f0583a6350a7c3c40c39fd1fa6f8d68").into(), + hex!("43276bee17fc9fba3f4866e902f0e5b5b308d79db91154bb8bf819973837a7d9").into(), + hex!("5572348e13ce59446ca0ea7cfeed07579da05f121920a76559e19bda94dd81cd").into(), + hex!("2d58adca9f3c742530de037f1933d6de1920ea4b68581613d4bc32b71547f221").into(), + hex!("7072b3c6577cd5a89b3234968f316f54630bb97eafbdb59e5b61637a9640255f").into(), ], }), finalized_header: BeaconHeader{ slot: 64, proposer_index: 4, - parent_root: hex!("0f7bc2353778c14c7f6dba0fc5fe6eec87228b0d3a5447b61dce67b4d9338de3").into(), - state_root: hex!("feb990de653ce494c0a263f820eaf05a9300dbdc30cb6065ede602827bfccde4").into(), - body_root: hex!("f5235cd8c24f2695fc5b7989926305c10ad8cf5a87d62a739f675f5543df2ec1").into(), + parent_root: hex!("a876486aaad7ddb897f369fd22d0a9903cd61d00c9e0dfe7998dd68d1008c678").into(), + state_root: hex!("818e21c3388575f8ccc9ff17ec79d5a57915bcd31bccf47770f65a18e068416b").into(), + body_root: hex!("1d1f73b864b3bb7e11ff91b56ca1381e0f9ca8122b2c542db88243604c763019").into(), }, finality_branch: vec![ hex!("0200000000000000000000000000000000000000000000000000000000000000").into(), hex!("10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7").into(), hex!("98e9116c6bb7f20de18800dc63e73e689d06d6a47d35b5e2b32cf093d475840d").into(), - hex!("e1c97f93bb7352d395d1ff8ee29881572cb7eb5d71634783701171dcd30cd93d").into(), - hex!("77fa2170ddbd89b15dae02f2e6cf9f76c8e00d1c4217320acffbe01576d0da61").into(), - hex!("e97288e0627219087a024078d69445f34f0583a6350a7c3c40c39fd1fa6f8d68").into(), + hex!("5572348e13ce59446ca0ea7cfeed07579da05f121920a76559e19bda94dd81cd").into(), + hex!("2d58adca9f3c742530de037f1933d6de1920ea4b68581613d4bc32b71547f221").into(), + hex!("7072b3c6577cd5a89b3234968f316f54630bb97eafbdb59e5b61637a9640255f").into(), ], - block_roots_root: hex!("6fcdfd1c3fb1bdd421fe59dddfff3855b5ed5e30373887991a0059d019ad12bc").into(), + block_roots_root: hex!("715b08694bef183a6d94b3113d16a7129f89fc3edec85a7e0eaf6ef9153552ef").into(), block_roots_branch: vec![ - hex!("94b59531f172bc24f914bc0c10104ccb158676850f8cc3b47b6ddb7f096ebdd7").into(), - hex!("22470ed9155a938587d44d5fa19217c0f939d8862e504e67cd8cb4d1b960795e").into(), - hex!("feec3ef1a68f93849e71e84f90b99602cccc31868137b6887ca8244a4b979e8e").into(), + hex!("4028c72c71b6ce80ea7d18b2c9471f4e4fa39746261a9921e832a4a2f9bdf7bb").into(), + hex!("75f98062661785d3290b7bd998b64446582baa49210733fd4603e1a97cd45a44").into(), + hex!("6fb757f44052f30c464810f01b0132adfa1a5446d8715b41e9af88eee1ee3e65").into(), hex!("5340ad5877c72dca689ca04bc8fedb78d67a4801d99887937edd8ccd29f87e82").into(), - hex!("f5ff4b0c6190005015889879568f5f0d9c40134c7ec4ffdda47950dcd92395ad").into(), + hex!("f2b3cb56753939a728ccad399a434ca490f018f2f331529ec0d8b2d59c509271").into(), ], }) } @@ -1131,95 +1132,180 @@ pub fn make_sync_committee_update() -> Box { pub fn make_finalized_header_update() -> Box { Box::new(Update { attested_header: BeaconHeader { - slot: 2566, - proposer_index: 6, - parent_root: hex!("6eb9f13a2c496318ce1ab3087bbd872f5c9519a1a7ca8231a2453e3cb523af00").into(), - state_root: hex!("c8cb12766113dff7e46d2917267bf33d0626d99dd47715fcdbc5c65fad3c04b4").into(), - body_root: hex!("d8cfd0d7bc9bc3724417a1655bb0a67c0765ca36197320f4d834150b52ef1420").into(), + slot: 933, + proposer_index: 1, + parent_root: hex!("f5fc63e2780ca302b97aea73fc95d74d702b5afe9a772c2b68f695026337b620").into(), + state_root: hex!("d856d11636bc4d866e78be9e747b222b0977556a367ab42e4085277301438050").into(), + body_root: hex!("5689091ab4eb76c2e876271add4924e1c66ce987c300c24aac2ad8c703e9a33f").into(), }, sync_aggregate: SyncAggregate{ sync_committee_bits: hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), - sync_committee_signature: hex!("9296f9a0387f2cac47008e22ad7c3cd3d49d35384c13e6aa1eacca7dca7c3d2ca81515e50eb3396b9550ed20ef7d8fa2049a186598feb2c00e93728045fcff917733d1827481b8fc95f3913e27fc70112c2490496eb57bb7181f02c3f9fd471f").into(), + sync_committee_signature: hex!("93a3d482fe2a2f7fd2b634169752a8fddf1dc28b23a020b398be8526faf37a74ca0f6db1bed78a9c7256c09a6115235e108e0e8a7ce09287317b0856c4b77dfa5adba6cf4c3ebea5bfa4cd2fcde80fd0a532f2defe65d530201d5d2258796559").into(), }, - signature_slot: 2567, + signature_slot: 934, next_sync_committee_update: None, finalized_header: BeaconHeader { - slot: 2496, - proposer_index: 2, - parent_root: hex!("c99e49787106733eeebab4d93eb326e1f2214575c9d928f0c4ab0da0776f1622").into(), - state_root: hex!("fbf8a08c86ef36bd173e37e733da4a78aa8e85fee99a990e858dd12a59087fde").into(), - body_root: hex!("a2a8ad06901447b2807a9059580a4c40d8a941f325b1343c69f7c7c6c90e4ab0").into(), + slot: 864, + proposer_index: 4, + parent_root: hex!("614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614").into(), + state_root: hex!("5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a").into(), + body_root: hex!("0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e").into(), }, finality_branch: vec![ - hex!("4e00000000000000000000000000000000000000000000000000000000000000").into(), + hex!("1b00000000000000000000000000000000000000000000000000000000000000").into(), hex!("10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7").into(), hex!("98e9116c6bb7f20de18800dc63e73e689d06d6a47d35b5e2b32cf093d475840d").into(), - hex!("958b8e43347f6df6fa5eb3d62d06a862381a6585aa40640dd1c0de11f1cf89c1").into(), - hex!("f107dce04faa86a28fc5d4a618be9cb8d4fc3c23d6c42c3624f3ff4bf6586a03").into(), - hex!("a501cdc02e86969ac3e4d0c5a36f4f049efaa1ab8cb6693f51d130eb52a80f30").into(), + hex!("f12d9aededc72724e417b518fe6f847684f26f81616243dedf8c551cc7d504f5").into(), + hex!("89a85d0907ab3fd6e00ae385f61d456c6191646404ae7b8d23d0e60440cf4d00").into(), + hex!("9fc943b6020eb61d780d78bcc6f6102a81d2c868d58f36e61c6e286a2dc4d8c2").into(), ], - block_roots_root: hex!("d160b7687041891b73e54b06fc4e04f82d0fa8fdd76705895e216c6b24709dfe").into(), + block_roots_root: hex!("b9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10").into(), block_roots_branch: vec![ - hex!("105290e42d98ab6a0ada6e55453cede36c672abf645eeb986b88d7487616e135").into(), - hex!("9da41f274bcdf6122335443d9ce94d07163b48dba3e2f9499ff56f4e48b48b99").into(), - hex!("ecea7e1d3152d8130e83afdfe34b4de4ba2b69a33c9471991096daf454de9cf5").into(), - hex!("b2bf1758e50b2bfff29169fbc70fdb884b2b05bb615dbc53567574da6f4f1ae2").into(), - hex!("cd87069daf70975779126d6af833b7d636c75ca4d5e750ebcad0e76408a5e5bf").into(), - ], + hex!("733422bd810895dab74cbbe07c69dd440cbb51f573181ad4dddac30fcdd0f41f").into(), + hex!("9b9eca73ab01d14549c325ba1b4610bb20bf1f8ec2dbd649f9d8cc7f3cea75fa").into(), + hex!("bcc666ad0ad9f9725cbd682bc95589d35b1b53b2a615f1e6e8dd5e086336becf").into(), + hex!("3069b547a08f703a1715016e926cbd64e71f93f64fb68d98d8c8f1ab745c46e5").into(), + hex!("c2de7e1097239404e17b263cfa0473533cc41e903cb03440d633bc5c27314cb4").into(), + ] }) } -pub fn make_execution_header_update() -> Box { - Box::new(ExecutionHeaderUpdate { +pub fn make_execution_proof() -> Box { + Box::new(ExecutionProof { header: BeaconHeader { - slot: 215, - proposer_index: 2, - parent_root: hex!("97518f531a252bb6ca547b21aca9da767943ec99211d3b15c804e34c3a523f45").into(), - state_root: hex!("b088b5a3a8c90d6dc919a695cd7bb0267c6f983ea2e675c559ceb8f46cb90b67").into(), - body_root: hex!("0ba23c8224fdd01531d5ad51486353bd524a0b4c20bca704e26d3210616f829b").into(), + slot: 393, + proposer_index: 4, + parent_root: hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + state_root: hex!("b62ac34a8cb82497be9542fe2114410c9f6021855b766015406101a1f3d86434").into(), + body_root: hex!("04005fe231e11a5b7b1580cb73b177ae8b338bedd745497e6bb7122126a806db").into(), }, ancestry_proof: Some(AncestryProof { header_branch: vec![ - hex!("97518f531a252bb6ca547b21aca9da767943ec99211d3b15c804e34c3a523f45").into(), - hex!("5ce0db996bd499c2b4f7a93263d5aafd052f420efb617cce6fdd54e25516aa45").into(), - hex!("84f0e373b66011ce774c7061440c0a50a51cce2b4b335395eee3e563d605597f").into(), - hex!("48f9ccc5f9594142c18c3b5c39a99f0549329c6ab3ba06c9a50030eadca87770").into(), - hex!("f89d6e311e05bc75a6f63ce118bccce254551f1a88d54c3b4f773f81f946bd99").into(), - hex!("2edd6d893c22636675147c07dfcdb541a146e87c3f15b51c388be4868246dc9b").into(), - hex!("d76b7de5f856e3208a91a42c9c398a7f4fab35e667bf916346050ae742514a2d").into(), - hex!("83a2e233e76385953ca41de4c3afe60471a61f0cc1b3846b4a0670e3e563b747").into(), - hex!("e783a5a109c2ad74e4eb53e8f6b11b31266a92a9e16c1fd5873109c5d41b282c").into(), - hex!("d4ea1ef3869ee6a0fd0b19d7d70027d144eecd4f1d32cbf47632a0a9069164b9").into(), - hex!("f8179564b58eb93a850d35e4156a04db651106442ad891c3e85155c1762792f1").into(), - hex!("4cbb1edb48cf1e32fb30db60aaaeaf6190ffe4d0c8dbc96cec307daecb78be12").into(), + hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + hex!("fa84cc88ca53a72181599ff4eb07d8b444bce023fe2347c3b4f51004c43439d3").into(), + hex!("cadc8ae211c6f2221c9138e829249adf902419c78eb4727a150baa4d9a02cc9d").into(), + hex!("33a89962df08a35c52bd7e1d887cd71fa7803e68787d05c714036f6edf75947c").into(), + hex!("2c9760fce5c2829ef3f25595a703c21eb22d0186ce223295556ed5da663a82cf").into(), + hex!("e1aa87654db79c8a0ecd6c89726bb662fcb1684badaef5cd5256f479e3c622e1").into(), + hex!("aa70d5f314e4a1fbb9c362f3db79b21bf68b328887248651fbd29fc501d0ca97").into(), + hex!("160b6c235b3a1ed4ef5f80b03ee1c76f7bf3f591c92fca9d8663e9221b9f9f0f").into(), + hex!("f68d7dcd6a07a18e9de7b5d2aa1980eb962e11d7dcb584c96e81a7635c8d2535").into(), + hex!("1d5f912dfd6697110dd1ecb5cb8e77952eef57d85deb373572572df62bb157fc").into(), + hex!("ffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b").into(), + hex!("6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220").into(), hex!("b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f").into(), ], - finalized_block_root: hex!("890a7f23b9ed2160901654be9efc575d6830ca860e2a97866ae3423fb7bd7231").into(), + finalized_block_root: hex!("751414cd97c0624f922b3e80285e9f776b08fa22fd5f87391f2ed7ef571a8d46").into(), }), execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { - parent_hash: hex!("d82ec63f5c5e6ba61d62f09c188f158e6449b94bdcc31941e68639eec3c4cf7a").into(), + parent_hash: hex!("8092290aa21b7751576440f77edd02a94058429ce50e63a92d620951fb25eda2").into(), fee_recipient: hex!("0000000000000000000000000000000000000000").into(), - state_root: hex!("8b65545fe5f3216b47b6339b9c91ca2b7f1032a970b04246d9e9fb4460ee34c3").into(), - receipts_root: hex!("7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095").into(), - logs_bloom: hex!("00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010").into(), - prev_randao: hex!("6d9e2a012d82b1b6cb0a2c1c1ed24cc16dbb56e6e39ae545371e0666ab057862").into(), - block_number: 215, - gas_limit: 64842908, - gas_used: 119301, - timestamp: 1705859527, - extra_data: hex!("d983010d0a846765746888676f312e32312e358664617277696e").into(), + state_root: hex!("96a83e9ddf745346fafcb0b03d57314623df669ed543c110662b21302a0fae8b").into(), + receipts_root: hex!("dccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284").into(), + logs_bloom: hex!("00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000400000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000040004000000000000002002002000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000200000200000010").into(), + prev_randao: hex!("62e309d4f5119d1f5c783abc20fc1a549efbab546d8d0b25ff1cfd58be524e67").into(), + block_number: 393, + gas_limit: 54492273, + gas_used: 199644, + timestamp: 1710552813, + extra_data: hex!("d983010d0b846765746888676f312e32312e368664617277696e").into(), base_fee_per_gas: U256::from(7u64), - block_hash: hex!("48498dbfbcfae53a7f4c289ee00747aceea925f6260c50ead5a33e1c55c40f98").into(), - transactions_root: hex!("5ebc1347fe3df0611d4f66b19bd8e1c6f4eaed0371d850f14c83b1c77ea234e6").into(), + block_hash: hex!("6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131").into(), + transactions_root: hex!("2cfa6ed7327e8807c7973516c5c32a68ef2459e586e8067e113d081c3bd8c07d").into(), withdrawals_root: hex!("792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535").into(), blob_gas_used: 0, excess_blob_gas: 0, }), execution_branch: vec![ - hex!("f8c69d3830406d668619bcccc13c8dddde41e863326f7418b241d5924c4ad34a").into(), + hex!("a6833fa629f3286b6916c6e50b8bf089fc9126bee6f64d0413b4e59c1265834d").into(), hex!("b46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb").into(), hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), - hex!("f4d6b5cf9c6e212615c3674fa625d04eb1114153fb221ef5ad02aa433fc67cfb").into(), + hex!("d3af7c05c516726be7505239e0b9c7cb53d24abce6b91cdb3b3995f0164a75da").into(), ], }) } + +pub fn make_inbound_fixture() -> InboundQueueFixture { + InboundQueueFixture { + message: Message { + event_log: Log { + address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), + topics: vec![ + hex!("7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f").into(), + hex!("c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539").into(), + hex!("5f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0").into(), + ], + data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000").into(), + }, + proof: Proof { + receipt_proof: (vec![ + hex!("dccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284").to_vec(), + hex!("4a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f").to_vec(), + ], vec![ + hex!("f851a09c01dd6d2d8de951c45af23d3ad00829ce021c04d6c8acbe1612d456ee320d4980808080808080a04a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f8080808080808080").to_vec(), + hex!("f9028c30b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000").to_vec(), + ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: 393, + proposer_index: 4, + parent_root: hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + state_root: hex!("b62ac34a8cb82497be9542fe2114410c9f6021855b766015406101a1f3d86434").into(), + body_root: hex!("04005fe231e11a5b7b1580cb73b177ae8b338bedd745497e6bb7122126a806db").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + hex!("fa84cc88ca53a72181599ff4eb07d8b444bce023fe2347c3b4f51004c43439d3").into(), + hex!("cadc8ae211c6f2221c9138e829249adf902419c78eb4727a150baa4d9a02cc9d").into(), + hex!("33a89962df08a35c52bd7e1d887cd71fa7803e68787d05c714036f6edf75947c").into(), + hex!("2c9760fce5c2829ef3f25595a703c21eb22d0186ce223295556ed5da663a82cf").into(), + hex!("e1aa87654db79c8a0ecd6c89726bb662fcb1684badaef5cd5256f479e3c622e1").into(), + hex!("aa70d5f314e4a1fbb9c362f3db79b21bf68b328887248651fbd29fc501d0ca97").into(), + hex!("160b6c235b3a1ed4ef5f80b03ee1c76f7bf3f591c92fca9d8663e9221b9f9f0f").into(), + hex!("f68d7dcd6a07a18e9de7b5d2aa1980eb962e11d7dcb584c96e81a7635c8d2535").into(), + hex!("1d5f912dfd6697110dd1ecb5cb8e77952eef57d85deb373572572df62bb157fc").into(), + hex!("ffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b").into(), + hex!("6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220").into(), + hex!("b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f").into(), + ], + finalized_block_root: hex!("751414cd97c0624f922b3e80285e9f776b08fa22fd5f87391f2ed7ef571a8d46").into(), + }), + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("8092290aa21b7751576440f77edd02a94058429ce50e63a92d620951fb25eda2").into(), + fee_recipient: hex!("0000000000000000000000000000000000000000").into(), + state_root: hex!("96a83e9ddf745346fafcb0b03d57314623df669ed543c110662b21302a0fae8b").into(), + receipts_root: hex!("dccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284").into(), + logs_bloom: hex!("00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000400000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000040004000000000000002002002000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000200000200000010").into(), + prev_randao: hex!("62e309d4f5119d1f5c783abc20fc1a549efbab546d8d0b25ff1cfd58be524e67").into(), + block_number: 393, + gas_limit: 54492273, + gas_used: 199644, + timestamp: 1710552813, + extra_data: hex!("d983010d0b846765746888676f312e32312e368664617277696e").into(), + base_fee_per_gas: U256::from(7u64), + block_hash: hex!("6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131").into(), + transactions_root: hex!("2cfa6ed7327e8807c7973516c5c32a68ef2459e586e8067e113d081c3bd8c07d").into(), + withdrawals_root: hex!("792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535").into(), + blob_gas_used: 0, + excess_blob_gas: 0, + }), + execution_branch: vec![ + hex!("a6833fa629f3286b6916c6e50b8bf089fc9126bee6f64d0413b4e59c1265834d").into(), + hex!("b46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("d3af7c05c516726be7505239e0b9c7cb53d24abce6b91cdb3b3995f0164a75da").into(), + ], + } + }, + }, + finalized_header: BeaconHeader { + slot: 864, + proposer_index: 4, + parent_root: hex!("614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614").into(), + state_root: hex!("5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a").into(), + body_root: hex!("0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e").into(), + }, + block_roots_root: hex!("b9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10").into(), + } +} diff --git a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs index e1520cd71539..4b8796b628d7 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/benchmarking/mod.rs @@ -65,24 +65,6 @@ mod benchmarks { Ok(()) } - #[benchmark] - fn submit_execution_header() -> Result<(), BenchmarkError> { - let caller: T::AccountId = whitelisted_caller(); - let checkpoint_update = make_checkpoint(); - let finalized_header_update = make_finalized_header_update(); - let execution_header_update = make_execution_header_update(); - let execution_header_hash = execution_header_update.execution_header.block_hash(); - EthereumBeaconClient::::process_checkpoint_update(&checkpoint_update)?; - EthereumBeaconClient::::process_update(&finalized_header_update)?; - - #[extrinsic_call] - _(RawOrigin::Signed(caller.clone()), Box::new(*execution_header_update)); - - assert!(>::contains_key(execution_header_hash)); - - Ok(()) - } - #[benchmark(extra)] fn bls_fast_aggregate_verify_pre_aggregated() -> Result<(), BenchmarkError> { EthereumBeaconClient::::process_checkpoint_update(&make_checkpoint())?; diff --git a/bridges/snowbridge/pallets/ethereum-client/src/impls.rs b/bridges/snowbridge/pallets/ethereum-client/src/impls.rs index 300431d87707..f600b1f67e29 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/impls.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/impls.rs @@ -1,6 +1,8 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use super::*; +use frame_support::ensure; +use primitives::ExecutionProof; use snowbridge_core::inbound::{ VerificationError::{self, *}, @@ -14,32 +16,13 @@ impl Verifier for Pallet { /// the log should be in the beacon client storage, meaning it has been verified and is an /// ancestor of a finalized beacon block. fn verify(event_log: &Log, proof: &Proof) -> Result<(), VerificationError> { - log::info!( - target: "ethereum-client", - "💫 Verifying message with block hash {}", - proof.block_hash, - ); + Self::verify_execution_proof(&proof.execution_proof) + .map_err(|e| InvalidExecutionProof(e.into()))?; - let header = >::get(proof.block_hash).ok_or(HeaderNotFound)?; - - let receipt = match Self::verify_receipt_inclusion(header.receipts_root, proof) { - Ok(receipt) => receipt, - Err(err) => { - log::error!( - target: "ethereum-client", - "💫 Verification of receipt inclusion failed for block {}: {:?}", - proof.block_hash, - err - ); - return Err(err) - }, - }; - - log::trace!( - target: "ethereum-client", - "💫 Verified receipt inclusion for transaction at index {} in block {}", - proof.tx_index, proof.block_hash, - ); + let receipt = Self::verify_receipt_inclusion( + proof.execution_proof.execution_header.receipts_root(), + &proof.receipt_proof.1, + )?; event_log.validate().map_err(|_| InvalidLog)?; @@ -53,18 +36,11 @@ impl Verifier for Pallet { if !receipt.contains_log(&event_log) { log::error!( target: "ethereum-client", - "💫 Event log not found in receipt for transaction at index {} in block {}", - proof.tx_index, proof.block_hash, + "💫 Event log not found in receipt for transaction", ); return Err(LogNotFound) } - log::info!( - target: "ethereum-client", - "💫 Receipt verification successful for {}", - proof.block_hash, - ); - Ok(()) } } @@ -74,9 +50,9 @@ impl Pallet { /// `proof.block_hash`. pub fn verify_receipt_inclusion( receipts_root: H256, - proof: &Proof, + receipt_proof: &[Vec], ) -> Result { - let result = verify_receipt_proof(receipts_root, &proof.data.1).ok_or(InvalidProof)?; + let result = verify_receipt_proof(receipts_root, receipt_proof).ok_or(InvalidProof)?; match result { Ok(receipt) => Ok(receipt), @@ -90,4 +66,96 @@ impl Pallet { }, } } + + /// Validates an execution header with ancestry_proof against a finalized checkpoint on + /// chain.The beacon header containing the execution header is sent, plus the execution header, + /// along with a proof that the execution header is rooted in the beacon header body. + pub(crate) fn verify_execution_proof(execution_proof: &ExecutionProof) -> DispatchResult { + let latest_finalized_state = + FinalizedBeaconState::::get(LatestFinalizedBlockRoot::::get()) + .ok_or(Error::::NotBootstrapped)?; + // Checks that the header is an ancestor of a finalized header, using slot number. + ensure!( + execution_proof.header.slot <= latest_finalized_state.slot, + Error::::HeaderNotFinalized + ); + + // Gets the hash tree root of the execution header, in preparation for the execution + // header proof (used to check that the execution header is rooted in the beacon + // header body. + let execution_header_root: H256 = execution_proof + .execution_header + .hash_tree_root() + .map_err(|_| Error::::BlockBodyHashTreeRootFailed)?; + + ensure!( + verify_merkle_branch( + execution_header_root, + &execution_proof.execution_branch, + config::EXECUTION_HEADER_SUBTREE_INDEX, + config::EXECUTION_HEADER_DEPTH, + execution_proof.header.body_root + ), + Error::::InvalidExecutionHeaderProof + ); + + let beacon_block_root: H256 = execution_proof + .header + .hash_tree_root() + .map_err(|_| Error::::HeaderHashTreeRootFailed)?; + + match &execution_proof.ancestry_proof { + Some(proof) => { + Self::verify_ancestry_proof( + beacon_block_root, + execution_proof.header.slot, + &proof.header_branch, + proof.finalized_block_root, + )?; + }, + None => { + // If the ancestry proof is not provided, we expect this beacon header to be a + // finalized beacon header. We need to check that the header hash matches the + // finalized header root at the expected slot. + let state = >::get(beacon_block_root) + .ok_or(Error::::ExpectedFinalizedHeaderNotStored)?; + if execution_proof.header.slot != state.slot { + return Err(Error::::ExpectedFinalizedHeaderNotStored.into()) + } + }, + } + + Ok(()) + } + + /// Verify that `block_root` is an ancestor of `finalized_block_root` Used to prove that + /// an execution header is an ancestor of a finalized header (i.e. the blocks are + /// on the same chain). + fn verify_ancestry_proof( + block_root: H256, + block_slot: u64, + block_root_proof: &[H256], + finalized_block_root: H256, + ) -> DispatchResult { + let state = >::get(finalized_block_root) + .ok_or(Error::::ExpectedFinalizedHeaderNotStored)?; + + ensure!(block_slot < state.slot, Error::::HeaderNotFinalized); + + let index_in_array = block_slot % (SLOTS_PER_HISTORICAL_ROOT as u64); + let leaf_index = (SLOTS_PER_HISTORICAL_ROOT as u64) + index_in_array; + + ensure!( + verify_merkle_branch( + block_root, + block_root_proof, + leaf_index as usize, + config::BLOCK_ROOT_AT_INDEX_DEPTH, + state.block_roots_root + ), + Error::::InvalidAncestryMerkleProof + ); + + Ok(()) + } } diff --git a/bridges/snowbridge/pallets/ethereum-client/src/lib.rs b/bridges/snowbridge/pallets/ethereum-client/src/lib.rs index ba47eeca5651..a8442b1e46ee 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/lib.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/lib.rs @@ -40,8 +40,7 @@ use frame_support::{ use frame_system::ensure_signed; use primitives::{ fast_aggregate_verify, verify_merkle_branch, verify_receipt_proof, BeaconHeader, BlsError, - CompactBeaconState, CompactExecutionHeader, ForkData, ForkVersion, ForkVersions, - PublicKeyPrepared, SigningData, + CompactBeaconState, ForkData, ForkVersion, ForkVersions, PublicKeyPrepared, SigningData, }; use snowbridge_core::{BasicOperatingMode, RingBufferMap}; use sp_core::H256; @@ -51,11 +50,7 @@ pub use weights::WeightInfo; use functions::{ compute_epoch, compute_period, decompress_sync_committee_bits, sync_committee_sum, }; -pub use types::ExecutionHeaderBuffer; -use types::{ - CheckpointUpdate, ExecutionHeaderUpdate, FinalizedBeaconStateBuffer, SyncCommitteePrepared, - Update, -}; +use types::{CheckpointUpdate, FinalizedBeaconStateBuffer, SyncCommitteePrepared, Update}; pub use pallet::*; @@ -76,10 +71,7 @@ pub mod pallet { pub struct MaxFinalizedHeadersToKeep(PhantomData); impl Get for MaxFinalizedHeadersToKeep { fn get() -> u32 { - // Consider max latency allowed between LatestFinalizedState and LatestExecutionState is - // the total slots in one sync_committee_period so 1 should be fine we keep 2 periods - // here for redundancy. - const MAX_REDUNDANCY: u32 = 2; + const MAX_REDUNDANCY: u32 = 20; config::EPOCHS_PER_SYNC_COMMITTEE_PERIOD as u32 * MAX_REDUNDANCY } } @@ -105,10 +97,6 @@ pub mod pallet { block_hash: H256, slot: u64, }, - ExecutionHeaderImported { - block_hash: H256, - block_number: u64, - }, SyncCommitteeUpdated { period: u64, }, @@ -191,19 +179,6 @@ pub mod pallet { pub(super) type NextSyncCommittee = StorageValue<_, SyncCommitteePrepared, ValueQuery>; - /// Execution Headers - #[pallet::storage] - pub type ExecutionHeaders = - StorageMap<_, Identity, H256, CompactExecutionHeader, OptionQuery>; - - /// Execution Headers: Current position in ring buffer - #[pallet::storage] - pub type ExecutionHeaderIndex = StorageValue<_, u32, ValueQuery>; - - /// Execution Headers: Mapping of ring buffer index to a pruning candidate - #[pallet::storage] - pub type ExecutionHeaderMapping = StorageMap<_, Identity, u32, H256, ValueQuery>; - /// The current operating mode of the pallet. #[pallet::storage] #[pallet::getter(fn operating_mode)] @@ -242,21 +217,6 @@ pub mod pallet { Ok(()) } - #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::submit_execution_header())] - #[transactional] - /// Submits a new execution header update. The relevant related beacon header - /// is also included to prove the execution header, as well as ancestry proof data. - pub fn submit_execution_header( - origin: OriginFor, - update: Box, - ) -> DispatchResult { - ensure_signed(origin)?; - ensure!(!Self::operating_mode().is_halted(), Error::::Halted); - Self::process_execution_header_update(&update)?; - Ok(()) - } - /// Halt or resume all pallet operations. May only be called by root. #[pallet::call_index(3)] #[pallet::weight((T::DbWeight::get().reads_writes(1, 1), DispatchClass::Operational))] @@ -321,7 +281,7 @@ pub mod pallet { InitialCheckpointRoot::::set(header_root); Self::store_validators_root(update.validators_root); - Self::store_finalized_header(header_root, update.header, update.block_roots_root)?; + Self::store_finalized_header(update.header, update.block_roots_root)?; Ok(()) } @@ -506,119 +466,12 @@ pub mod pallet { }; if update.finalized_header.slot > latest_finalized_state.slot { - let finalized_block_root: H256 = update - .finalized_header - .hash_tree_root() - .map_err(|_| Error::::HeaderHashTreeRootFailed)?; - Self::store_finalized_header( - finalized_block_root, - update.finalized_header, - update.block_roots_root, - )?; + Self::store_finalized_header(update.finalized_header, update.block_roots_root)?; } Ok(()) } - /// Validates an execution header for import. The beacon header containing the execution - /// header is sent, plus the execution header, along with a proof that the execution header - /// is rooted in the beacon header body. - pub(crate) fn process_execution_header_update( - update: &ExecutionHeaderUpdate, - ) -> DispatchResult { - let latest_finalized_state = - FinalizedBeaconState::::get(LatestFinalizedBlockRoot::::get()) - .ok_or(Error::::NotBootstrapped)?; - // Checks that the header is an ancestor of a finalized header, using slot number. - ensure!( - update.header.slot <= latest_finalized_state.slot, - Error::::HeaderNotFinalized - ); - - // Gets the hash tree root of the execution header, in preparation for the execution - // header proof (used to check that the execution header is rooted in the beacon - // header body. - let execution_header_root: H256 = update - .execution_header - .hash_tree_root() - .map_err(|_| Error::::BlockBodyHashTreeRootFailed)?; - - ensure!( - verify_merkle_branch( - execution_header_root, - &update.execution_branch, - config::EXECUTION_HEADER_SUBTREE_INDEX, - config::EXECUTION_HEADER_DEPTH, - update.header.body_root - ), - Error::::InvalidExecutionHeaderProof - ); - - let block_root: H256 = update - .header - .hash_tree_root() - .map_err(|_| Error::::HeaderHashTreeRootFailed)?; - - match &update.ancestry_proof { - Some(proof) => { - Self::verify_ancestry_proof( - block_root, - update.header.slot, - &proof.header_branch, - proof.finalized_block_root, - )?; - }, - None => { - // If the ancestry proof is not provided, 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. - let state = >::get(block_root) - .ok_or(Error::::ExpectedFinalizedHeaderNotStored)?; - if update.header.slot != state.slot { - return Err(Error::::ExpectedFinalizedHeaderNotStored.into()) - } - }, - } - - Self::store_execution_header( - update.execution_header.block_hash(), - update.execution_header.clone().into(), - ); - - Ok(()) - } - - /// Verify that `block_root` is an ancestor of `finalized_block_root` Used to prove that - /// an execution header is an ancestor of a finalized header (i.e. the blocks are - /// on the same chain). - fn verify_ancestry_proof( - block_root: H256, - block_slot: u64, - block_root_proof: &[H256], - finalized_block_root: H256, - ) -> DispatchResult { - let state = >::get(finalized_block_root) - .ok_or(Error::::ExpectedFinalizedHeaderNotStored)?; - - ensure!(block_slot < state.slot, Error::::HeaderNotFinalized); - - let index_in_array = block_slot % (SLOTS_PER_HISTORICAL_ROOT as u64); - let leaf_index = (SLOTS_PER_HISTORICAL_ROOT as u64) + index_in_array; - - ensure!( - verify_merkle_branch( - block_root, - block_root_proof, - leaf_index as usize, - config::BLOCK_ROOT_AT_INDEX_DEPTH, - state.block_roots_root - ), - Error::::InvalidAncestryMerkleProof - ); - - Ok(()) - } - /// Computes the signing root for a given beacon header and domain. The hash tree root /// of the beacon header is computed, and then the combination of the beacon header hash /// and the domain makes up the signing root. @@ -640,13 +493,15 @@ pub mod pallet { /// Stores a compacted (slot and block roots root (hash of the `block_roots` beacon state /// field, used for ancestry proof)) beacon state in a ring buffer map, with the header root /// as map key. - fn store_finalized_header( - header_root: H256, + pub fn store_finalized_header( header: BeaconHeader, block_roots_root: H256, ) -> DispatchResult { let slot = header.slot; + let header_root: H256 = + header.hash_tree_root().map_err(|_| Error::::HeaderHashTreeRootFailed)?; + >::insert( header_root, CompactBeaconState { slot: header.slot, block_roots_root }, @@ -665,24 +520,6 @@ pub mod pallet { Ok(()) } - /// Stores the provided execution header in pallet storage. The header is stored - /// in a ring buffer map, with the block hash as map key. The last imported execution - /// header is also kept in storage, for the relayer to check import progress. - pub fn store_execution_header(block_hash: H256, header: CompactExecutionHeader) { - let block_number = header.block_number; - - >::insert(block_hash, header); - - log::trace!( - target: LOG_TARGET, - "💫 Updated latest execution block at {} to number {}.", - block_hash, - block_number - ); - - Self::deposit_event(Event::ExecutionHeaderImported { block_hash, block_number }); - } - /// Stores the validators root in storage. Validators root is the hash tree root of all the /// validators at genesis and is used to used to identify the chain that we are on /// (used in conjunction with the fork version). diff --git a/bridges/snowbridge/pallets/ethereum-client/src/mock.rs b/bridges/snowbridge/pallets/ethereum-client/src/mock.rs index 3ce34eee191a..b27835ab25d7 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/mock.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/mock.rs @@ -2,12 +2,13 @@ // SPDX-FileCopyrightText: 2023 Snowfork use crate as ethereum_beacon_client; use crate::config; -use frame_support::{derive_impl, parameter_types}; -use hex_literal::hex; +use frame_support::{derive_impl, dispatch::DispatchResult, parameter_types}; use pallet_timestamp; -use primitives::{CompactExecutionHeader, Fork, ForkVersions}; +use primitives::{Fork, ForkVersions}; use snowbridge_core::inbound::{Log, Proof}; +use sp_std::default::Default; use std::{fs::File, path::PathBuf}; + type Block = frame_system::mocking::MockBlock; use sp_runtime::BuildStorage; @@ -20,8 +21,8 @@ where serde_json::from_reader(File::open(filepath).unwrap()) } -pub fn load_execution_header_update_fixture() -> primitives::ExecutionHeaderUpdate { - load_fixture("execution-header-update.json".to_string()).unwrap() +pub fn load_execution_proof_fixture() -> primitives::ExecutionProof { + load_fixture("execution-proof.json".to_string()).unwrap() } pub fn load_checkpoint_update_fixture( @@ -50,41 +51,8 @@ pub fn load_next_finalized_header_update_fixture( } pub fn get_message_verification_payload() -> (Log, Proof) { - ( - Log { - address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), - topics: vec![ - hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), - hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), - hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), - ], - data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), - }, - Proof { - block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), - tx_index: 0, - data: (vec![ - hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb").to_vec(), - hex!("d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c185510").to_vec(), - hex!("b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646").to_vec(), - ], vec![ - hex!("f90131a0b601337b3aa10a671caa724eba641e759399979856141d3aea6b6b4ac59b889ba00c7d5dd48be9060221a02fb8fa213860b4c50d47046c8fa65ffaba5737d569e0a094601b62a1086cd9c9cb71a7ebff9e718f3217fd6e837efe4246733c0a196f63a06a4b0dd0aefc37b3c77828c8f07d1b7a2455ceb5dbfd3c77d7d6aeeddc2f7e8ca0d6e8e23142cdd8ec219e1f5d8b56aa18e456702b195deeaa210327284d42ade4a08a313d4c87023005d1ab631bbfe3f5de1e405d0e66d0bef3e033f1e5711b5521a0bf09a5d9a48b10ade82b8d6a5362a15921c8b5228a3487479b467db97411d82fa0f95cccae2a7c572ef3c566503e30bac2b2feb2d2f26eebf6d870dcf7f8cf59cea0d21fc4f68ab05bc4dcb23c67008e92c4d466437cdd6ed7aad0c008944c1855108080808080808080").to_vec(), - hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), - hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), - ]), - } - ) -} - -pub fn get_message_verification_header() -> CompactExecutionHeader { - CompactExecutionHeader { - parent_hash: hex!("04a7f6ab8282203562c62f38b0ab41d32aaebe2c7ea687702b463148a6429e04") - .into(), - block_number: 55, - state_root: hex!("894d968712976d613519f973a317cb0781c7b039c89f27ea2b7ca193f7befdb3").into(), - receipts_root: hex!("cf0d1c1ba57d1e0edfb59786c7e30c2b7e12bd54612b00cd21c4eaeecedf44fb") - .into(), - } + let inbound_fixture = snowbridge_pallet_ethereum_client_fixtures::make_inbound_fixture(); + (inbound_fixture.message.event_log, inbound_fixture.message.proof) } frame_support::construct_runtime!( @@ -143,7 +111,14 @@ impl ethereum_beacon_client::Config for Test { // Build genesis storage according to the mock runtime. pub fn new_tester() -> sp_io::TestExternalities { let t = frame_system::GenesisConfig::::default().build_storage().unwrap(); - let mut ext = sp_io::TestExternalities::new(t); - let _ = ext.execute_with(|| Timestamp::set(RuntimeOrigin::signed(1), 30_000)); + let ext = sp_io::TestExternalities::new(t); ext } + +pub fn initialize_storage() -> DispatchResult { + let inbound_fixture = snowbridge_pallet_ethereum_client_fixtures::make_inbound_fixture(); + EthereumBeaconClient::store_finalized_header( + inbound_fixture.finalized_header, + inbound_fixture.block_roots_root, + ) +} diff --git a/bridges/snowbridge/pallets/ethereum-client/src/tests.rs b/bridges/snowbridge/pallets/ethereum-client/src/tests.rs index deb9977f3b35..2da66f17a8bf 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/tests.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/tests.rs @@ -1,14 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use crate::{ - functions::compute_period, pallet::ExecutionHeaders, sync_committee_sum, verify_merkle_branch, - BeaconHeader, CompactBeaconState, Error, ExecutionHeaderBuffer, FinalizedBeaconState, - LatestFinalizedBlockRoot, NextSyncCommittee, SyncCommitteePrepared, + functions::compute_period, sync_committee_sum, verify_merkle_branch, BeaconHeader, + CompactBeaconState, Error, FinalizedBeaconState, LatestFinalizedBlockRoot, NextSyncCommittee, + SyncCommitteePrepared, }; use crate::mock::{ - get_message_verification_header, get_message_verification_payload, - load_checkpoint_update_fixture, load_execution_header_update_fixture, + get_message_verification_payload, load_checkpoint_update_fixture, load_finalized_header_update_fixture, load_next_finalized_header_update_fixture, load_next_sync_committee_update_fixture, load_sync_committee_update_fixture, }; @@ -18,12 +17,10 @@ pub use crate::mock::*; use crate::config::{EPOCHS_PER_SYNC_COMMITTEE_PERIOD, SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT}; use frame_support::{assert_err, assert_noop, assert_ok}; use hex_literal::hex; -use primitives::{CompactExecutionHeader, Fork, ForkVersions, NextSyncCommitteeUpdate}; -use rand::{thread_rng, Rng}; -use snowbridge_core::{ - inbound::{VerificationError, Verifier}, - RingBufferMap, +use primitives::{ + types::deneb, Fork, ForkVersions, NextSyncCommitteeUpdate, VersionedExecutionPayloadHeader, }; +use snowbridge_core::inbound::{VerificationError, Verifier}; use sp_core::H256; use sp_runtime::DispatchError; @@ -209,51 +206,6 @@ pub fn sync_committee_participation_is_supermajority_errors_when_not_supermajori }); } -#[test] -pub fn execution_header_pruning() { - new_tester().execute_with(|| { - let execution_header_prune_threshold = ExecutionHeadersPruneThreshold::get(); - let to_be_deleted = execution_header_prune_threshold / 2; - - let mut stored_hashes = vec![]; - - for _ in 0..execution_header_prune_threshold { - let mut hash = H256::default(); - thread_rng().try_fill(&mut hash.0[..]).unwrap(); - EthereumBeaconClient::store_execution_header(hash, CompactExecutionHeader::default()); - stored_hashes.push(hash); - } - - // We should have stored everything until now - assert_eq!({ ExecutionHeaders::::iter().count() }, stored_hashes.len()); - - // Let's push extra entries so that some of the previous entries are deleted. - for _ in 0..to_be_deleted { - let mut hash = H256::default(); - thread_rng().try_fill(&mut hash.0[..]).unwrap(); - EthereumBeaconClient::store_execution_header(hash, CompactExecutionHeader::default()); - - stored_hashes.push(hash); - } - - // We should have only stored upto `execution_header_prune_threshold` - assert_eq!( - ExecutionHeaders::::iter().count() as u32, - execution_header_prune_threshold - ); - - // First `to_be_deleted` items must be deleted - for i in 0..to_be_deleted { - assert!(!ExecutionHeaders::::contains_key(stored_hashes[i as usize])); - } - - // Other entries should be part of data - for i in to_be_deleted..(to_be_deleted + execution_header_prune_threshold) { - assert!(ExecutionHeaders::::contains_key(stored_hashes[i as usize])); - } - }); -} - #[test] fn compute_fork_version() { let mock_fork_versions = ForkVersions { @@ -628,142 +580,6 @@ fn submit_update_with_invalid_sync_committee_update() { }); } -#[test] -fn submit_execution_header_update() { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let execution_header_update = Box::new(load_execution_header_update_fixture()); - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - assert_ok!(EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update.clone() - )); - assert!(>::contains_key( - execution_header_update.execution_header.block_hash() - )); - }); -} - -#[test] -fn submit_execution_header_update_invalid_ancestry_proof() { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let mut execution_header_update = Box::new(load_execution_header_update_fixture()); - if let Some(ref mut ancestry_proof) = execution_header_update.ancestry_proof { - ancestry_proof.header_branch[0] = TEST_HASH.into() - } - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - assert_err!( - EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update - ), - Error::::InvalidAncestryMerkleProof - ); - }); -} - -#[test] -fn submit_execution_header_update_invalid_execution_header_proof() { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let mut execution_header_update = Box::new(load_execution_header_update_fixture()); - execution_header_update.execution_branch[0] = TEST_HASH.into(); - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - assert_err!( - EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update - ), - Error::::InvalidExecutionHeaderProof - ); - }); -} - -#[test] -fn submit_execution_header_update_that_is_also_finalized_header_which_is_not_stored() { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let mut execution_header_update = Box::new(load_execution_header_update_fixture()); - execution_header_update.ancestry_proof = None; - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - assert_err!( - EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update - ), - Error::::ExpectedFinalizedHeaderNotStored - ); - }); -} - -#[test] -fn submit_execution_header_update_that_is_also_finalized_header_which_is_stored_but_slots_dont_match( -) { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let mut execution_header_update = Box::new(load_execution_header_update_fixture()); - execution_header_update.ancestry_proof = None; - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - - let block_root: H256 = execution_header_update.header.hash_tree_root().unwrap(); - - >::insert( - block_root, - CompactBeaconState { - slot: execution_header_update.header.slot + 1, - block_roots_root: Default::default(), - }, - ); - LatestFinalizedBlockRoot::::set(block_root); - - assert_err!( - EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update - ), - Error::::ExpectedFinalizedHeaderNotStored - ); - }); -} - -#[test] -fn submit_execution_header_not_finalized() { - let checkpoint = Box::new(load_checkpoint_update_fixture()); - let finalized_header_update = Box::new(load_finalized_header_update_fixture()); - let update = Box::new(load_execution_header_update_fixture()); - - new_tester().execute_with(|| { - assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); - assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); - - >::mutate(>::get(), |x| { - let prev = x.unwrap(); - *x = Some(CompactBeaconState { slot: update.header.slot - 1, ..prev }); - }); - - assert_err!( - EthereumBeaconClient::submit_execution_header(RuntimeOrigin::signed(1), update), - Error::::HeaderNotFinalized - ); - }); -} - /// Check that a gap of more than 8192 slots between finalized headers is not allowed. #[test] fn submit_finalized_header_update_with_too_large_gap() { @@ -818,42 +634,25 @@ fn submit_finalized_header_update_with_gap_at_limit() { ); }); } - /* IMPLS */ #[test] fn verify_message() { - let header = get_message_verification_header(); let (event_log, proof) = get_message_verification_payload(); - let block_hash = proof.block_hash; new_tester().execute_with(|| { - >::insert(block_hash, header); + assert_ok!(initialize_storage()); assert_ok!(EthereumBeaconClient::verify(&event_log, &proof)); }); } -#[test] -fn verify_message_missing_header() { - let (event_log, proof) = get_message_verification_payload(); - - new_tester().execute_with(|| { - assert_err!( - EthereumBeaconClient::verify(&event_log, &proof), - VerificationError::HeaderNotFound - ); - }); -} - #[test] fn verify_message_invalid_proof() { - let header = get_message_verification_header(); let (event_log, mut proof) = get_message_verification_payload(); - proof.data.1[0] = TEST_HASH.into(); - let block_hash = proof.block_hash; + proof.receipt_proof.1[0] = TEST_HASH.into(); new_tester().execute_with(|| { - >::insert(block_hash, header); + assert_ok!(initialize_storage()); assert_err!( EthereumBeaconClient::verify(&event_log, &proof), VerificationError::InvalidProof @@ -863,29 +662,28 @@ fn verify_message_invalid_proof() { #[test] fn verify_message_invalid_receipts_root() { - let mut header = get_message_verification_header(); - let (event_log, proof) = get_message_verification_payload(); - let block_hash = proof.block_hash; - header.receipts_root = TEST_HASH.into(); + let (event_log, mut proof) = get_message_verification_payload(); + let mut payload = deneb::ExecutionPayloadHeader::default(); + payload.receipts_root = TEST_HASH.into(); + proof.execution_proof.execution_header = VersionedExecutionPayloadHeader::Deneb(payload); new_tester().execute_with(|| { - >::insert(block_hash, header); + assert_ok!(initialize_storage()); assert_err!( EthereumBeaconClient::verify(&event_log, &proof), - VerificationError::InvalidProof + VerificationError::InvalidExecutionProof( + Error::::BlockBodyHashTreeRootFailed.into() + ) ); }); } #[test] fn verify_message_invalid_log() { - let header = get_message_verification_header(); let (mut event_log, proof) = get_message_verification_payload(); - let block_hash = proof.block_hash; event_log.topics = vec![H256::zero(); 10]; - new_tester().execute_with(|| { - >::insert(block_hash, header); + assert_ok!(initialize_storage()); assert_err!( EthereumBeaconClient::verify(&event_log, &proof), VerificationError::InvalidLog @@ -895,13 +693,11 @@ fn verify_message_invalid_log() { #[test] fn verify_message_receipt_does_not_contain_log() { - let header = get_message_verification_header(); let (mut event_log, proof) = get_message_verification_payload(); - let block_hash = proof.block_hash; event_log.data = hex!("f9013c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000002b8c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000068000f000000000000000101d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec70100000101001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0000e8890423c78a0000000000000000000000000000000000000000000000000000000000000000").to_vec(); new_tester().execute_with(|| { - >::insert(block_hash, header); + assert_ok!(initialize_storage()); assert_err!( EthereumBeaconClient::verify(&event_log, &proof), VerificationError::LogNotFound @@ -913,7 +709,6 @@ fn verify_message_receipt_does_not_contain_log() { fn set_operating_mode() { let checkpoint = Box::new(load_checkpoint_update_fixture()); let update = Box::new(load_finalized_header_update_fixture()); - let execution_header_update = Box::new(load_execution_header_update_fixture()); new_tester().execute_with(|| { assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); @@ -927,14 +722,6 @@ fn set_operating_mode() { EthereumBeaconClient::submit(RuntimeOrigin::signed(1), update), Error::::Halted ); - - assert_noop!( - EthereumBeaconClient::submit_execution_header( - RuntimeOrigin::signed(1), - execution_header_update - ), - Error::::Halted - ); }); } @@ -950,3 +737,107 @@ fn set_operating_mode_root_only() { ); }); } + +#[test] +fn verify_execution_proof_invalid_ancestry_proof() { + let checkpoint = Box::new(load_checkpoint_update_fixture()); + let finalized_header_update = Box::new(load_finalized_header_update_fixture()); + let mut execution_header_update = Box::new(load_execution_proof_fixture()); + if let Some(ref mut ancestry_proof) = execution_header_update.ancestry_proof { + ancestry_proof.header_branch[0] = TEST_HASH.into() + } + + new_tester().execute_with(|| { + assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); + assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); + assert_err!( + EthereumBeaconClient::verify_execution_proof(&execution_header_update), + Error::::InvalidAncestryMerkleProof + ); + }); +} + +#[test] +fn verify_execution_proof_invalid_execution_header_proof() { + let checkpoint = Box::new(load_checkpoint_update_fixture()); + let finalized_header_update = Box::new(load_finalized_header_update_fixture()); + let mut execution_header_update = Box::new(load_execution_proof_fixture()); + execution_header_update.execution_branch[0] = TEST_HASH.into(); + + new_tester().execute_with(|| { + assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); + assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); + assert_err!( + EthereumBeaconClient::verify_execution_proof(&execution_header_update), + Error::::InvalidExecutionHeaderProof + ); + }); +} + +#[test] +fn verify_execution_proof_that_is_also_finalized_header_which_is_not_stored() { + let checkpoint = Box::new(load_checkpoint_update_fixture()); + let finalized_header_update = Box::new(load_finalized_header_update_fixture()); + let mut execution_header_update = Box::new(load_execution_proof_fixture()); + execution_header_update.ancestry_proof = None; + + new_tester().execute_with(|| { + assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); + assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); + assert_err!( + EthereumBeaconClient::verify_execution_proof(&execution_header_update), + Error::::ExpectedFinalizedHeaderNotStored + ); + }); +} + +#[test] +fn submit_execution_proof_that_is_also_finalized_header_which_is_stored_but_slots_dont_match() { + let checkpoint = Box::new(load_checkpoint_update_fixture()); + let finalized_header_update = Box::new(load_finalized_header_update_fixture()); + let mut execution_header_update = Box::new(load_execution_proof_fixture()); + execution_header_update.ancestry_proof = None; + + new_tester().execute_with(|| { + assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); + assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); + + let block_root: H256 = execution_header_update.header.hash_tree_root().unwrap(); + + >::insert( + block_root, + CompactBeaconState { + slot: execution_header_update.header.slot + 1, + block_roots_root: Default::default(), + }, + ); + LatestFinalizedBlockRoot::::set(block_root); + + assert_err!( + EthereumBeaconClient::verify_execution_proof(&execution_header_update), + Error::::ExpectedFinalizedHeaderNotStored + ); + }); +} + +#[test] +fn verify_execution_proof_not_finalized() { + let checkpoint = Box::new(load_checkpoint_update_fixture()); + let finalized_header_update = Box::new(load_finalized_header_update_fixture()); + let update = Box::new(load_execution_proof_fixture()); + + new_tester().execute_with(|| { + assert_ok!(EthereumBeaconClient::process_checkpoint_update(&checkpoint)); + assert_ok!(EthereumBeaconClient::submit(RuntimeOrigin::signed(1), finalized_header_update)); + + >::mutate(>::get(), |x| { + let prev = x.unwrap(); + *x = Some(CompactBeaconState { slot: update.header.slot - 1, ..prev }); + }); + + assert_err!( + EthereumBeaconClient::verify_execution_proof(&update), + Error::::HeaderNotFinalized + ); + }); +} diff --git a/bridges/snowbridge/pallets/ethereum-client/src/types.rs b/bridges/snowbridge/pallets/ethereum-client/src/types.rs index 5dcefea9f80f..8808f989754b 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/types.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/types.rs @@ -15,17 +15,7 @@ pub type CheckpointUpdate = primitives::CheckpointUpdate; pub type Update = primitives::Update; pub type NextSyncCommitteeUpdate = primitives::NextSyncCommitteeUpdate; -pub use primitives::ExecutionHeaderUpdate; - -/// ExecutionHeader ring buffer implementation -pub type ExecutionHeaderBuffer = RingBufferMapImpl< - u32, - ::MaxExecutionHeadersToKeep, - crate::ExecutionHeaderIndex, - crate::ExecutionHeaderMapping, - crate::ExecutionHeaders, - OptionQuery, ->; +pub use primitives::{AncestryProof, ExecutionProof}; /// FinalizedState ring buffer implementation pub(crate) type FinalizedBeaconStateBuffer = RingBufferMapImpl< diff --git a/bridges/snowbridge/pallets/ethereum-client/src/weights.rs b/bridges/snowbridge/pallets/ethereum-client/src/weights.rs index e1a5578f4661..e4629746aa2d 100644 --- a/bridges/snowbridge/pallets/ethereum-client/src/weights.rs +++ b/bridges/snowbridge/pallets/ethereum-client/src/weights.rs @@ -36,7 +36,6 @@ pub trait WeightInfo { fn force_checkpoint() -> Weight; fn submit() -> Weight; fn submit_with_sync_committee() -> Weight; - fn submit_execution_header() -> Weight; } // For backwards compatibility and tests @@ -59,10 +58,4 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(6)) .saturating_add(RocksDbWeight::get().writes(1)) } - fn submit_execution_header() -> Weight { - Weight::from_parts(113_158_000_u64, 0) - .saturating_add(Weight::from_parts(0, 3537)) - .saturating_add(RocksDbWeight::get().reads(5)) - .saturating_add(RocksDbWeight::get().writes(4)) - } } diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-header-update.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-header-update.json deleted file mode 100755 index 319014249c12..000000000000 --- a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-header-update.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "header": { - "slot": 215, - "proposer_index": 2, - "parent_root": "0x97518f531a252bb6ca547b21aca9da767943ec99211d3b15c804e34c3a523f45", - "state_root": "0xb088b5a3a8c90d6dc919a695cd7bb0267c6f983ea2e675c559ceb8f46cb90b67", - "body_root": "0x0ba23c8224fdd01531d5ad51486353bd524a0b4c20bca704e26d3210616f829b" - }, - "ancestry_proof": { - "header_branch": [ - "0x97518f531a252bb6ca547b21aca9da767943ec99211d3b15c804e34c3a523f45", - "0x5ce0db996bd499c2b4f7a93263d5aafd052f420efb617cce6fdd54e25516aa45", - "0x84f0e373b66011ce774c7061440c0a50a51cce2b4b335395eee3e563d605597f", - "0x48f9ccc5f9594142c18c3b5c39a99f0549329c6ab3ba06c9a50030eadca87770", - "0xf89d6e311e05bc75a6f63ce118bccce254551f1a88d54c3b4f773f81f946bd99", - "0x2edd6d893c22636675147c07dfcdb541a146e87c3f15b51c388be4868246dc9b", - "0xd76b7de5f856e3208a91a42c9c398a7f4fab35e667bf916346050ae742514a2d", - "0x83a2e233e76385953ca41de4c3afe60471a61f0cc1b3846b4a0670e3e563b747", - "0xe783a5a109c2ad74e4eb53e8f6b11b31266a92a9e16c1fd5873109c5d41b282c", - "0xd4ea1ef3869ee6a0fd0b19d7d70027d144eecd4f1d32cbf47632a0a9069164b9", - "0xf8179564b58eb93a850d35e4156a04db651106442ad891c3e85155c1762792f1", - "0x4cbb1edb48cf1e32fb30db60aaaeaf6190ffe4d0c8dbc96cec307daecb78be12", - "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f" - ], - "finalized_block_root": "0x890a7f23b9ed2160901654be9efc575d6830ca860e2a97866ae3423fb7bd7231" - }, - "execution_header": { - "Deneb": { - "parent_hash": "0xd82ec63f5c5e6ba61d62f09c188f158e6449b94bdcc31941e68639eec3c4cf7a", - "fee_recipient": "0x0000000000000000000000000000000000000000", - "state_root": "0x8b65545fe5f3216b47b6339b9c91ca2b7f1032a970b04246d9e9fb4460ee34c3", - "receipts_root": "0x7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095", - "logs_bloom": "0x00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010", - "prev_randao": "0x6d9e2a012d82b1b6cb0a2c1c1ed24cc16dbb56e6e39ae545371e0666ab057862", - "block_number": 215, - "gas_limit": 64842908, - "gas_used": 119301, - "timestamp": 1705859527, - "extra_data": "0xd983010d0a846765746888676f312e32312e358664617277696e", - "base_fee_per_gas": 7, - "block_hash": "0x48498dbfbcfae53a7f4c289ee00747aceea925f6260c50ead5a33e1c55c40f98", - "transactions_root": "0x5ebc1347fe3df0611d4f66b19bd8e1c6f4eaed0371d850f14c83b1c77ea234e6", - "withdrawals_root": "0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535", - "blob_gas_used": 0, - "excess_blob_gas": 0 - } - }, - "execution_branch": [ - "0xf8c69d3830406d668619bcccc13c8dddde41e863326f7418b241d5924c4ad34a", - "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", - "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", - "0xf4d6b5cf9c6e212615c3674fa625d04eb1114153fb221ef5ad02aa433fc67cfb" - ] -} \ No newline at end of file diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-proof.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-proof.json new file mode 100755 index 000000000000..f55898087dfe --- /dev/null +++ b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/execution-proof.json @@ -0,0 +1,54 @@ +{ + "header": { + "slot": 393, + "proposer_index": 4, + "parent_root": "0x6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef", + "state_root": "0xb62ac34a8cb82497be9542fe2114410c9f6021855b766015406101a1f3d86434", + "body_root": "0x04005fe231e11a5b7b1580cb73b177ae8b338bedd745497e6bb7122126a806db" + }, + "ancestry_proof": { + "header_branch": [ + "0x6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef", + "0xfa84cc88ca53a72181599ff4eb07d8b444bce023fe2347c3b4f51004c43439d3", + "0xcadc8ae211c6f2221c9138e829249adf902419c78eb4727a150baa4d9a02cc9d", + "0x33a89962df08a35c52bd7e1d887cd71fa7803e68787d05c714036f6edf75947c", + "0x2c9760fce5c2829ef3f25595a703c21eb22d0186ce223295556ed5da663a82cf", + "0xe1aa87654db79c8a0ecd6c89726bb662fcb1684badaef5cd5256f479e3c622e1", + "0xaa70d5f314e4a1fbb9c362f3db79b21bf68b328887248651fbd29fc501d0ca97", + "0x160b6c235b3a1ed4ef5f80b03ee1c76f7bf3f591c92fca9d8663e9221b9f9f0f", + "0xf68d7dcd6a07a18e9de7b5d2aa1980eb962e11d7dcb584c96e81a7635c8d2535", + "0x1d5f912dfd6697110dd1ecb5cb8e77952eef57d85deb373572572df62bb157fc", + "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f" + ], + "finalized_block_root": "0x751414cd97c0624f922b3e80285e9f776b08fa22fd5f87391f2ed7ef571a8d46" + }, + "execution_header": { + "Deneb": { + "parent_hash": "0x8092290aa21b7751576440f77edd02a94058429ce50e63a92d620951fb25eda2", + "fee_recipient": "0x0000000000000000000000000000000000000000", + "state_root": "0x96a83e9ddf745346fafcb0b03d57314623df669ed543c110662b21302a0fae8b", + "receipts_root": "0xdccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284", + "logs_bloom": "0x00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000400000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000040004000000000000002002002000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000200000200000010", + "prev_randao": "0x62e309d4f5119d1f5c783abc20fc1a549efbab546d8d0b25ff1cfd58be524e67", + "block_number": 393, + "gas_limit": 54492273, + "gas_used": 199644, + "timestamp": 1710552813, + "extra_data": "0xd983010d0b846765746888676f312e32312e368664617277696e", + "base_fee_per_gas": 7, + "block_hash": "0x6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131", + "transactions_root": "0x2cfa6ed7327e8807c7973516c5c32a68ef2459e586e8067e113d081c3bd8c07d", + "withdrawals_root": "0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535", + "blob_gas_used": 0, + "excess_blob_gas": 0 + } + }, + "execution_branch": [ + "0xa6833fa629f3286b6916c6e50b8bf089fc9126bee6f64d0413b4e59c1265834d", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0xd3af7c05c516726be7505239e0b9c7cb53d24abce6b91cdb3b3995f0164a75da" + ] +} \ No newline at end of file diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/finalized-header-update.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/finalized-header-update.json index f9d5324d57b1..2dec5cc56fac 100755 --- a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/finalized-header-update.json +++ b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/finalized-header-update.json @@ -1,38 +1,40 @@ { "attested_header": { - "slot": 2566, - "proposer_index": 6, - "parent_root": "0x6eb9f13a2c496318ce1ab3087bbd872f5c9519a1a7ca8231a2453e3cb523af00", - "state_root": "0xc8cb12766113dff7e46d2917267bf33d0626d99dd47715fcdbc5c65fad3c04b4", - "body_root": "0xd8cfd0d7bc9bc3724417a1655bb0a67c0765ca36197320f4d834150b52ef1420" + "slot": 933, + "proposer_index": 1, + "parent_root": "0xf5fc63e2780ca302b97aea73fc95d74d702b5afe9a772c2b68f695026337b620", + "state_root": "0xd856d11636bc4d866e78be9e747b222b0977556a367ab42e4085277301438050", + "body_root": "0x5689091ab4eb76c2e876271add4924e1c66ce987c300c24aac2ad8c703e9a33f" }, "sync_aggregate": { "sync_committee_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "sync_committee_signature": "0x9296f9a0387f2cac47008e22ad7c3cd3d49d35384c13e6aa1eacca7dca7c3d2ca81515e50eb3396b9550ed20ef7d8fa2049a186598feb2c00e93728045fcff917733d1827481b8fc95f3913e27fc70112c2490496eb57bb7181f02c3f9fd471f" + "sync_committee_signature": "0x93a3d482fe2a2f7fd2b634169752a8fddf1dc28b23a020b398be8526faf37a74ca0f6db1bed78a9c7256c09a6115235e108e0e8a7ce09287317b0856c4b77dfa5adba6cf4c3ebea5bfa4cd2fcde80fd0a532f2defe65d530201d5d2258796559" }, - "signature_slot": 2567, + "signature_slot": 934, "next_sync_committee_update": null, "finalized_header": { - "slot": 2496, - "proposer_index": 2, - "parent_root": "0xc99e49787106733eeebab4d93eb326e1f2214575c9d928f0c4ab0da0776f1622", - "state_root": "0xfbf8a08c86ef36bd173e37e733da4a78aa8e85fee99a990e858dd12a59087fde", - "body_root": "0xa2a8ad06901447b2807a9059580a4c40d8a941f325b1343c69f7c7c6c90e4ab0" + "slot": 864, + "proposer_index": 4, + "parent_root": "0x614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614", + "state_root": "0x5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a", + "body_root": "0x0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e" }, "finality_branch": [ - "0x4e00000000000000000000000000000000000000000000000000000000000000", + "0x1b00000000000000000000000000000000000000000000000000000000000000", "0x10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7", "0x98e9116c6bb7f20de18800dc63e73e689d06d6a47d35b5e2b32cf093d475840d", - "0x958b8e43347f6df6fa5eb3d62d06a862381a6585aa40640dd1c0de11f1cf89c1", - "0xf107dce04faa86a28fc5d4a618be9cb8d4fc3c23d6c42c3624f3ff4bf6586a03", - "0xa501cdc02e86969ac3e4d0c5a36f4f049efaa1ab8cb6693f51d130eb52a80f30" + "0xf12d9aededc72724e417b518fe6f847684f26f81616243dedf8c551cc7d504f5", + "0x89a85d0907ab3fd6e00ae385f61d456c6191646404ae7b8d23d0e60440cf4d00", + "0x9fc943b6020eb61d780d78bcc6f6102a81d2c868d58f36e61c6e286a2dc4d8c2" ], - "block_roots_root": "0xd160b7687041891b73e54b06fc4e04f82d0fa8fdd76705895e216c6b24709dfe", + "block_roots_root": "0xb9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10", "block_roots_branch": [ - "0x105290e42d98ab6a0ada6e55453cede36c672abf645eeb986b88d7487616e135", - "0x9da41f274bcdf6122335443d9ce94d07163b48dba3e2f9499ff56f4e48b48b99", - "0xecea7e1d3152d8130e83afdfe34b4de4ba2b69a33c9471991096daf454de9cf5", - "0xb2bf1758e50b2bfff29169fbc70fdb884b2b05bb615dbc53567574da6f4f1ae2", - "0xcd87069daf70975779126d6af833b7d636c75ca4d5e750ebcad0e76408a5e5bf" - ] + "0x733422bd810895dab74cbbe07c69dd440cbb51f573181ad4dddac30fcdd0f41f", + "0x9b9eca73ab01d14549c325ba1b4610bb20bf1f8ec2dbd649f9d8cc7f3cea75fa", + "0xbcc666ad0ad9f9725cbd682bc95589d35b1b53b2a615f1e6e8dd5e086336becf", + "0x3069b547a08f703a1715016e926cbd64e71f93f64fb68d98d8c8f1ab745c46e5", + "0xc2de7e1097239404e17b263cfa0473533cc41e903cb03440d633bc5c27314cb4" + ], + "execution_header": null, + "execution_branch": null } \ No newline at end of file diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/inbound-message.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/inbound-message.json index 5aa5a59f0237..6589dca5fb45 100644 --- a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/inbound-message.json +++ b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/inbound-message.json @@ -1,31 +1,79 @@ { - "execution_header": { - "parent_hash": "0xd82ec63f5c5e6ba61d62f09c188f158e6449b94bdcc31941e68639eec3c4cf7a", - "state_root": "0x8b65545fe5f3216b47b6339b9c91ca2b7f1032a970b04246d9e9fb4460ee34c3", - "receipts_root": "0x7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095", - "block_number": 215 + "event_log": { + "address": "0xeda338e4dc46038493b885327842fd3e301cab39", + "topics": [ + "0x7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f", + "0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539", + "0x5f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0" + ], + "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000" }, - "message": { - "event_log": { - "address": "0xeda338e4dc46038493b885327842fd3e301cab39", - "topics": [ - "0x7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f", - "0xc173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539", - "0x5f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0" + "proof": { + "block_hash": "0x6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131", + "tx_index": 0, + "receipt_proof": { + "keys": [ + "0xdccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284", + "0x4a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000" + "values": [ + "0xf851a09c01dd6d2d8de951c45af23d3ad00829ce021c04d6c8acbe1612d456ee320d4980808080808080a04a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f8080808080808080", + "0xf9028c30b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000" + ] }, - "Proof": { - "block_hash": "0x48498dbfbcfae53a7f4c289ee00747aceea925f6260c50ead5a33e1c55c40f98", - "tx_index": 0, - "data": { - "keys": [ - "0x7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095" + "execution_proof": { + "header": { + "slot": 393, + "proposer_index": 4, + "parent_root": "0x6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef", + "state_root": "0xb62ac34a8cb82497be9542fe2114410c9f6021855b766015406101a1f3d86434", + "body_root": "0x04005fe231e11a5b7b1580cb73b177ae8b338bedd745497e6bb7122126a806db" + }, + "ancestry_proof": { + "header_branch": [ + "0x6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef", + "0xfa84cc88ca53a72181599ff4eb07d8b444bce023fe2347c3b4f51004c43439d3", + "0xcadc8ae211c6f2221c9138e829249adf902419c78eb4727a150baa4d9a02cc9d", + "0x33a89962df08a35c52bd7e1d887cd71fa7803e68787d05c714036f6edf75947c", + "0x2c9760fce5c2829ef3f25595a703c21eb22d0186ce223295556ed5da663a82cf", + "0xe1aa87654db79c8a0ecd6c89726bb662fcb1684badaef5cd5256f479e3c622e1", + "0xaa70d5f314e4a1fbb9c362f3db79b21bf68b328887248651fbd29fc501d0ca97", + "0x160b6c235b3a1ed4ef5f80b03ee1c76f7bf3f591c92fca9d8663e9221b9f9f0f", + "0xf68d7dcd6a07a18e9de7b5d2aa1980eb962e11d7dcb584c96e81a7635c8d2535", + "0x1d5f912dfd6697110dd1ecb5cb8e77952eef57d85deb373572572df62bb157fc", + "0xffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b", + "0x6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220", + "0xb7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f" ], - "values": [ - "0xf9028e822080b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000" - ] - } + "finalized_block_root": "0x751414cd97c0624f922b3e80285e9f776b08fa22fd5f87391f2ed7ef571a8d46" + }, + "execution_header": { + "Deneb": { + "parent_hash": "0x8092290aa21b7751576440f77edd02a94058429ce50e63a92d620951fb25eda2", + "fee_recipient": "0x0000000000000000000000000000000000000000", + "state_root": "0x96a83e9ddf745346fafcb0b03d57314623df669ed543c110662b21302a0fae8b", + "receipts_root": "0xdccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284", + "logs_bloom": "0x00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000400000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000040004000000000000002002002000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000200000200000010", + "prev_randao": "0x62e309d4f5119d1f5c783abc20fc1a549efbab546d8d0b25ff1cfd58be524e67", + "block_number": 393, + "gas_limit": 54492273, + "gas_used": 199644, + "timestamp": 1710552813, + "extra_data": "0xd983010d0b846765746888676f312e32312e368664617277696e", + "base_fee_per_gas": 7, + "block_hash": "0x6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131", + "transactions_root": "0x2cfa6ed7327e8807c7973516c5c32a68ef2459e586e8067e113d081c3bd8c07d", + "withdrawals_root": "0x792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535", + "blob_gas_used": 0, + "excess_blob_gas": 0 + } + }, + "execution_branch": [ + "0xa6833fa629f3286b6916c6e50b8bf089fc9126bee6f64d0413b4e59c1265834d", + "0xb46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb", + "0xdb56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71", + "0xd3af7c05c516726be7505239e0b9c7cb53d24abce6b91cdb3b3995f0164a75da" + ] } } } \ No newline at end of file diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/initial-checkpoint.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/initial-checkpoint.json index 202790c1db5b..a62d646617e4 100755 --- a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/initial-checkpoint.json +++ b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/initial-checkpoint.json @@ -1,10 +1,10 @@ { "header": { - "slot": 2496, - "proposer_index": 2, - "parent_root": "0xc99e49787106733eeebab4d93eb326e1f2214575c9d928f0c4ab0da0776f1622", - "state_root": "0xfbf8a08c86ef36bd173e37e733da4a78aa8e85fee99a990e858dd12a59087fde", - "body_root": "0xa2a8ad06901447b2807a9059580a4c40d8a941f325b1343c69f7c7c6c90e4ab0" + "slot": 864, + "proposer_index": 4, + "parent_root": "0x614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614", + "state_root": "0x5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a", + "body_root": "0x0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e" }, "current_sync_committee": { "pubkeys": [ @@ -525,18 +525,18 @@ }, "current_sync_committee_branch": [ "0x3ade38d498a062b50880a9409e1ca3a7fd4315d91eeb3bb83e56ac6bfe8d6a59", - "0x93880225bf99a0c5ec22b266ff829837754e9c5edf37a68c05b8f803fd82fa45", - "0x4c60656ec9a95fcf11030ad309c716b5b15beb7f60a0bcfc7c9d4eff505472ff", - "0x22d1645fceb4bf9a695043dda19a53e784ec70df6a6b1bd66ea30eba1cca5f2f", - "0xa8fc6cad84ceefc633ec56c2d031d525e1cb4b51c70eb252919fce5bba9a1fde" + "0xa9e90f89e7f90fd5d79a6bbcaf40ba5cfc05ab1b561ac51c84867c32248d5b1e", + "0xbd1a76b03e02402bb24a627de1980a80ab17691980271f597b844b89b497ef75", + "0x07bbcd27c7cad089023db046eda17e8209842b7d97add8b873519e84fe6480e7", + "0x94c11eeee4cb6192bf40810f23486d8c75dfbc2b6f28d988d6f74435ede243b0" ], "validators_root": "0x270d43e74ce340de4bca2b1936beca0f4f5408d9e78aec4850920baf659d5b69", - "block_roots_root": "0xd160b7687041891b73e54b06fc4e04f82d0fa8fdd76705895e216c6b24709dfe", + "block_roots_root": "0xb9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10", "block_roots_branch": [ - "0x105290e42d98ab6a0ada6e55453cede36c672abf645eeb986b88d7487616e135", - "0x9da41f274bcdf6122335443d9ce94d07163b48dba3e2f9499ff56f4e48b48b99", - "0xecea7e1d3152d8130e83afdfe34b4de4ba2b69a33c9471991096daf454de9cf5", - "0xb2bf1758e50b2bfff29169fbc70fdb884b2b05bb615dbc53567574da6f4f1ae2", - "0xcd87069daf70975779126d6af833b7d636c75ca4d5e750ebcad0e76408a5e5bf" + "0x733422bd810895dab74cbbe07c69dd440cbb51f573181ad4dddac30fcdd0f41f", + "0x9b9eca73ab01d14549c325ba1b4610bb20bf1f8ec2dbd649f9d8cc7f3cea75fa", + "0xbcc666ad0ad9f9725cbd682bc95589d35b1b53b2a615f1e6e8dd5e086336becf", + "0x3069b547a08f703a1715016e926cbd64e71f93f64fb68d98d8c8f1ab745c46e5", + "0xc2de7e1097239404e17b263cfa0473533cc41e903cb03440d633bc5c27314cb4" ] } \ No newline at end of file diff --git a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/sync-committee-update.json b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/sync-committee-update.json index 6bf20355c7a3..4d601d7d8f0b 100755 --- a/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/sync-committee-update.json +++ b/bridges/snowbridge/pallets/ethereum-client/tests/fixtures/sync-committee-update.json @@ -2,13 +2,13 @@ "attested_header": { "slot": 129, "proposer_index": 5, - "parent_root": "0xe32b6c18f029e755b0273dc1c4fa2bc4979794c8286ad40276c1b8a8e36049d8", - "state_root": "0x5ec9dacf25a5f09f20be0c59246b3d8dcfe64bd085b4bac5cec180690339801e", - "body_root": "0x4080cf2412d6ff77fc3164ad6155423a7112f207f173145ec16371a93f481f87" + "parent_root": "0xc2def03fe44a2802130ca1a6d8406e4ccf4f344fec7075d4d84431cd4a8b0904", + "state_root": "0xfa62cde6666add7353d7aedcb61ebe3c6c84b5361e34f814825b1250affb5be4", + "body_root": "0x0f9c69f243fe7b5fa5860396c66c720a9e8b1e526e7914188930497cc4a9134c" }, "sync_aggregate": { "sync_committee_bits": "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "sync_committee_signature": "0xa761c3333fbb3d36bc8f65454f898da38001499dcd37494cf3d86940a995399ae649216ba4c985af154f83f72c8b1856079b7636a7a8d7d3f7602df2cbf699edb72b65253e82de4d9cc4db7377eafb22f799129f63f094a21c00675bdd5cc243" + "sync_committee_signature": "0x810cfde2afea3e276256c09bdf1cd321c33dcadeefddcfd24f488e6f756d917cfda90b5b437b3a4b4ef880985afa28a40cf565ec0a82877ddee36adc01d55d9d4a911ae3e22556e4c2636f1c707366fba019fb49450440fcd263d0b054b04bf0" }, "signature_slot": 130, "next_sync_committee_update": { @@ -531,33 +531,35 @@ }, "next_sync_committee_branch": [ "0x3ade38d498a062b50880a9409e1ca3a7fd4315d91eeb3bb83e56ac6bfe8d6a59", - "0xfd1e5ff5d4a15081efe3ff17857b1f95984c9a271b1c41c2f81f43e60c2cc541", - "0xe1c97f93bb7352d395d1ff8ee29881572cb7eb5d71634783701171dcd30cd93d", - "0x77fa2170ddbd89b15dae02f2e6cf9f76c8e00d1c4217320acffbe01576d0da61", - "0xe97288e0627219087a024078d69445f34f0583a6350a7c3c40c39fd1fa6f8d68" + "0x43276bee17fc9fba3f4866e902f0e5b5b308d79db91154bb8bf819973837a7d9", + "0x5572348e13ce59446ca0ea7cfeed07579da05f121920a76559e19bda94dd81cd", + "0x2d58adca9f3c742530de037f1933d6de1920ea4b68581613d4bc32b71547f221", + "0x7072b3c6577cd5a89b3234968f316f54630bb97eafbdb59e5b61637a9640255f" ] }, "finalized_header": { "slot": 64, "proposer_index": 4, - "parent_root": "0x0f7bc2353778c14c7f6dba0fc5fe6eec87228b0d3a5447b61dce67b4d9338de3", - "state_root": "0xfeb990de653ce494c0a263f820eaf05a9300dbdc30cb6065ede602827bfccde4", - "body_root": "0xf5235cd8c24f2695fc5b7989926305c10ad8cf5a87d62a739f675f5543df2ec1" + "parent_root": "0xa876486aaad7ddb897f369fd22d0a9903cd61d00c9e0dfe7998dd68d1008c678", + "state_root": "0x818e21c3388575f8ccc9ff17ec79d5a57915bcd31bccf47770f65a18e068416b", + "body_root": "0x1d1f73b864b3bb7e11ff91b56ca1381e0f9ca8122b2c542db88243604c763019" }, "finality_branch": [ "0x0200000000000000000000000000000000000000000000000000000000000000", "0x10c726fac935bf9657cc7476d3cfa7bedec5983dcfb59e8a7df6d0a619e108d7", "0x98e9116c6bb7f20de18800dc63e73e689d06d6a47d35b5e2b32cf093d475840d", - "0xe1c97f93bb7352d395d1ff8ee29881572cb7eb5d71634783701171dcd30cd93d", - "0x77fa2170ddbd89b15dae02f2e6cf9f76c8e00d1c4217320acffbe01576d0da61", - "0xe97288e0627219087a024078d69445f34f0583a6350a7c3c40c39fd1fa6f8d68" + "0x5572348e13ce59446ca0ea7cfeed07579da05f121920a76559e19bda94dd81cd", + "0x2d58adca9f3c742530de037f1933d6de1920ea4b68581613d4bc32b71547f221", + "0x7072b3c6577cd5a89b3234968f316f54630bb97eafbdb59e5b61637a9640255f" ], - "block_roots_root": "0x6fcdfd1c3fb1bdd421fe59dddfff3855b5ed5e30373887991a0059d019ad12bc", + "block_roots_root": "0x715b08694bef183a6d94b3113d16a7129f89fc3edec85a7e0eaf6ef9153552ef", "block_roots_branch": [ - "0x94b59531f172bc24f914bc0c10104ccb158676850f8cc3b47b6ddb7f096ebdd7", - "0x22470ed9155a938587d44d5fa19217c0f939d8862e504e67cd8cb4d1b960795e", - "0xfeec3ef1a68f93849e71e84f90b99602cccc31868137b6887ca8244a4b979e8e", + "0x4028c72c71b6ce80ea7d18b2c9471f4e4fa39746261a9921e832a4a2f9bdf7bb", + "0x75f98062661785d3290b7bd998b64446582baa49210733fd4603e1a97cd45a44", + "0x6fb757f44052f30c464810f01b0132adfa1a5446d8715b41e9af88eee1ee3e65", "0x5340ad5877c72dca689ca04bc8fedb78d67a4801d99887937edd8ccd29f87e82", - "0xf5ff4b0c6190005015889879568f5f0d9c40134c7ec4ffdda47950dcd92395ad" - ] + "0xf2b3cb56753939a728ccad399a434ca490f018f2f331529ec0d8b2d59c509271" + ], + "execution_header": null, + "execution_branch": null } \ No newline at end of file diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/lib.rs b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/lib.rs index 4f3445b29053..00adcdfa186a 100644 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/lib.rs +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/lib.rs @@ -2,17 +2,6 @@ // SPDX-FileCopyrightText: 2023 Snowfork #![cfg_attr(not(feature = "std"), no_std)] -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::Message; -use sp_core::RuntimeDebug; - pub mod register_token; -pub mod register_token_with_insufficient_fee; pub mod send_token; pub mod send_token_to_penpal; - -#[derive(Clone, RuntimeDebug)] -pub struct InboundQueueFixture { - pub execution_header: CompactExecutionHeader, - pub message: Message, -} diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token.rs b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token.rs index b8d510e6b13d..340b2fadfacf 100644 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token.rs +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token.rs @@ -3,20 +3,16 @@ // Generated, do not edit! // See ethereum client README.md for instructions to generate -use crate::InboundQueueFixture; use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; +use snowbridge_beacon_primitives::{ + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; use sp_std::vec; pub fn make_register_token_message() -> InboundQueueFixture { InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("d5de3dd02c96dbdc8aaa4db70a1e9fdab5ded5f4d52f18798acd56a3d37d1ad6").into(), - block_number: 772, - state_root: hex!("49cba2a79b23ad74cefe80c3a96699825d1cda0f75bfceb587c5549211c86245").into(), - receipts_root: hex!("7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095").into(), - }, message: Message { event_log: Log { address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), @@ -28,14 +24,74 @@ pub fn make_register_token_message() -> InboundQueueFixture { data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000").into(), }, proof: Proof { - block_hash: hex!("392182a385b3a417e8ddea8b252953ee81e6ec0fb09d9056c96c89fbeb703a3f").into(), - tx_index: 0, - data: (vec![ - hex!("7b1f61b9714c080ef0be014e01657a15f45f0304b477beebc7ca5596c8033095").to_vec(), + receipt_proof: (vec![ + hex!("dccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284").to_vec(), + hex!("4a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f").to_vec(), ], vec![ - hex!("f9028e822080b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000").to_vec(), + hex!("f851a09c01dd6d2d8de951c45af23d3ad00829ce021c04d6c8acbe1612d456ee320d4980808080808080a04a98e45a319168b0fc6005ce6b744ee9bf54338e2c0784b976a8578d241ced0f8080808080808080").to_vec(), + hex!("f9028c30b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d00e40b54020000000000000000000000000000000000000000000000000000000000").to_vec(), ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: 393, + proposer_index: 4, + parent_root: hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + state_root: hex!("b62ac34a8cb82497be9542fe2114410c9f6021855b766015406101a1f3d86434").into(), + body_root: hex!("04005fe231e11a5b7b1580cb73b177ae8b338bedd745497e6bb7122126a806db").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("6545b47a614a1dd4cad042a0cdbbf5be347e8ffcdc02c6c64540d5153acebeef").into(), + hex!("fa84cc88ca53a72181599ff4eb07d8b444bce023fe2347c3b4f51004c43439d3").into(), + hex!("cadc8ae211c6f2221c9138e829249adf902419c78eb4727a150baa4d9a02cc9d").into(), + hex!("33a89962df08a35c52bd7e1d887cd71fa7803e68787d05c714036f6edf75947c").into(), + hex!("2c9760fce5c2829ef3f25595a703c21eb22d0186ce223295556ed5da663a82cf").into(), + hex!("e1aa87654db79c8a0ecd6c89726bb662fcb1684badaef5cd5256f479e3c622e1").into(), + hex!("aa70d5f314e4a1fbb9c362f3db79b21bf68b328887248651fbd29fc501d0ca97").into(), + hex!("160b6c235b3a1ed4ef5f80b03ee1c76f7bf3f591c92fca9d8663e9221b9f9f0f").into(), + hex!("f68d7dcd6a07a18e9de7b5d2aa1980eb962e11d7dcb584c96e81a7635c8d2535").into(), + hex!("1d5f912dfd6697110dd1ecb5cb8e77952eef57d85deb373572572df62bb157fc").into(), + hex!("ffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b").into(), + hex!("6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220").into(), + hex!("b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f").into(), + ], + finalized_block_root: hex!("751414cd97c0624f922b3e80285e9f776b08fa22fd5f87391f2ed7ef571a8d46").into(), + }), + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("8092290aa21b7751576440f77edd02a94058429ce50e63a92d620951fb25eda2").into(), + fee_recipient: hex!("0000000000000000000000000000000000000000").into(), + state_root: hex!("96a83e9ddf745346fafcb0b03d57314623df669ed543c110662b21302a0fae8b").into(), + receipts_root: hex!("dccdfceea05036f7b61dcdabadc937945d31e68a8d3dfd4dc85684457988c284").into(), + logs_bloom: hex!("00000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000400000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000080000000000000000000000000000040004000000000000002002002000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000200000200000010").into(), + prev_randao: hex!("62e309d4f5119d1f5c783abc20fc1a549efbab546d8d0b25ff1cfd58be524e67").into(), + block_number: 393, + gas_limit: 54492273, + gas_used: 199644, + timestamp: 1710552813, + extra_data: hex!("d983010d0b846765746888676f312e32312e368664617277696e").into(), + base_fee_per_gas: U256::from(7u64), + block_hash: hex!("6a9810efb9581d30c1a5c9074f27c68ea779a8c1ae31c213241df16225f4e131").into(), + transactions_root: hex!("2cfa6ed7327e8807c7973516c5c32a68ef2459e586e8067e113d081c3bd8c07d").into(), + withdrawals_root: hex!("792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535").into(), + blob_gas_used: 0, + excess_blob_gas: 0, + }), + execution_branch: vec![ + hex!("a6833fa629f3286b6916c6e50b8bf089fc9126bee6f64d0413b4e59c1265834d").into(), + hex!("b46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("d3af7c05c516726be7505239e0b9c7cb53d24abce6b91cdb3b3995f0164a75da").into(), + ], + } }, }, + finalized_header: BeaconHeader { + slot: 864, + proposer_index: 4, + parent_root: hex!("614e7672f991ac268cd841055973f55e1e42228831a211adef207bb7329be614").into(), + state_root: hex!("5fa8dfca3d760e4242ab46d529144627aa85348a19173b6e081172c701197a4a").into(), + body_root: hex!("0f34c083b1803666bb1ac5e73fa71582731a2cf37d279ff0a3b0cad5a2ff371e").into(), + }, + block_roots_root: hex!("b9aab9c388c4e4fcd899b71f62c498fc73406e38e8eb14aa440e9affa06f2a10").into(), } } diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token_with_insufficient_fee.rs b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token_with_insufficient_fee.rs deleted file mode 100644 index 82ff2283101e..000000000000 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/register_token_with_insufficient_fee.rs +++ /dev/null @@ -1,42 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork -// Generated, do not edit! -// See ethereum client README.md for instructions to generate - -use crate::InboundQueueFixture; -use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; -use sp_std::vec; - -pub fn make_register_token_with_infufficient_fee_message() -> InboundQueueFixture { - InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("998e81dc6df788a920b67e058fbde0dc3f4ec6f11f3f7cd8c3148e6d99584885").into(), - block_number: 338, - state_root: hex!("30ef9c9db2609de19bbc6c3cbeddac889e82bbcb2db20304b3abdfbdc7134cbf").into(), - receipts_root: hex!("969335c3132a007cb8b5886a3c23dd8da63cba04aeda29857a86ee1c13dae782").into(), - }, - message: Message { - event_log: Log { - address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), - topics: vec![ - hex!("7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f").into(), - hex!("c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539").into(), - hex!("5f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0").into(), - ], - // insufficient xcm fee as only 1000(hex:e803) - data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7de8030000000000000000000000000000000000000000000000000000000000000000").into(), - }, - proof: Proof { - block_hash: hex!("5976f37f0e331d194eb331df74355ef47565c3a1bd11c95a45b681f6917085c1").into(), - tx_index: 0, - data: (vec![ - hex!("969335c3132a007cb8b5886a3c23dd8da63cba04aeda29857a86ee1c13dae782").to_vec(), - ], vec![ - hex!("f9028e822080b9028802f90284018301d205b9010000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000080000000000000000000000000000004000000000080000000000000000000000000000000000010100000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000040004000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000200000000000010f90179f85894eda338e4dc46038493b885327842fd3e301cab39e1a0f78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7ea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7df9011c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a05f7060e971b0dc81e63f0aa41831091847d97c1a4693ac450cc128c7214e65e0b8a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000002e00a736aa00000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7de8030000000000000000000000000000000000000000000000000000000000000000").to_vec(), - ]), - }, - }, - } -} diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token.rs b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token.rs index 2562217100ea..4075febab59d 100755 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token.rs +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token.rs @@ -3,20 +3,16 @@ // Generated, do not edit! // See ethereum client README.md for instructions to generate -use crate::InboundQueueFixture; use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; +use snowbridge_beacon_primitives::{ + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; use sp_std::vec; pub fn make_send_token_message() -> InboundQueueFixture { InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("920cecde45d428e3a77590b70f8533cf4c2c36917b8a7b74c915e7fa3dae7075").into(), - block_number: 1148, - state_root: hex!("bbc6ba0e9940d641afecbbaf3f97abd2b9ffaf2f6bd4879c4a71e659eca89978").into(), - receipts_root: hex!("9f3340b57eddc1f86de30776db57faeca80269a3dd459031741988dec240ce34").into(), - }, message: Message { event_log: Log { address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), @@ -28,14 +24,72 @@ pub fn make_send_token_message() -> InboundQueueFixture { data: hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005f00a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000").into(), }, proof: Proof { - block_hash: hex!("d3c155f123c3cbff22f3d7869283e02179edea9ffa7a5e9a4d8414c2a6b8991f").into(), - tx_index: 0, - data: (vec![ - hex!("9f3340b57eddc1f86de30776db57faeca80269a3dd459031741988dec240ce34").to_vec(), + receipt_proof: (vec![ + hex!("f9d844c5b79638609ba385b910fec3b5d891c9d7b189f135f0432f33473de915").to_vec(), ], vec![ - hex!("f90451822080b9044b02f90447018301bcb9b9010000800000000000000000000020000000000000000000004000000000000000000400000000000000000000001000000010000000000000000000000008000000200000000000000001000008000000000000000000000000000000008000080000000000200000000000000000000000000100000000000000000011000000000000020200000000000000000000000000003000000040080008000000000000000000040044000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200800000000000f9033cf89b9487d1f7fdfee7f651fabc8bfcb6e086c278b77a7df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000057a2d4ff0c3866d96556884bf09fecdd7ccd530ca00000000000000000000000000000000000000000000000000de0b6b3a7640000f9015d94eda338e4dc46038493b885327842fd3e301cab39f884a024c5d2de620c6e25186ae16f6919eba93b6e2c1a33857cc419d9f3a00d6967e9a000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7da000000000000000000000000000000000000000000000000000000000000003e8b8c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48f9013c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a0c8eaf22f2cb07bac4679df0a660e7115ed87fcfd4e32ac269f6540265bbbd26fb8c000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005f00a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000").to_vec(), + hex!("f90451822080b9044b02f90447018301bcb6b9010000800000000000000000000020000000000000000000004000000000000000000400000000000000000000001000000010000000000000000000000008000000200000000000000001000008000000000000000000000000000000008000080000000000200000000000000000000000000100000000000000000011000000000000020200000000000000000000000000003000000040080008000000000000000000040044000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200800000000000f9033cf89b9487d1f7fdfee7f651fabc8bfcb6e086c278b77a7df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000057a2d4ff0c3866d96556884bf09fecdd7ccd530ca00000000000000000000000000000000000000000000000000de0b6b3a7640000f9015d94eda338e4dc46038493b885327842fd3e301cab39f884a024c5d2de620c6e25186ae16f6919eba93b6e2c1a33857cc419d9f3a00d6967e9a000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7da000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000000000000000000000000000000000000000003e8b8c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000208eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48f9013c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a0c8eaf22f2cb07bac4679df0a660e7115ed87fcfd4e32ac269f6540265bbbd26fb8c000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000005f00a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d008eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000").to_vec(), ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: 2321, + proposer_index: 5, + parent_root: hex!("2add14727840d3a5ea061e14baa47030bb81380a65999200d119e73b86411d20").into(), + state_root: hex!("d962981467920bb2b7efa4a7a1baf64745582c3250857f49a957c5dae9a0da39").into(), + body_root: hex!("18e3f7f51a350f371ad35d166f2683b42af51d1836b295e4093be08acb0dcb7a").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("2add14727840d3a5ea061e14baa47030bb81380a65999200d119e73b86411d20").into(), + hex!("48b2e2f5256906a564e5058698f70e3406765fefd6a2edc064bb5fb88aa2ed0a").into(), + hex!("e5ed7c704e845418219b2fda42cd2f3438ffbe4c4b320935ae49439c6189f7a7").into(), + hex!("4a7ce24526b3f571548ad69679e4e260653a1b3b911a344e7f988f25a5c917a7").into(), + hex!("46fc859727ab0d0e8c344011f7d7a4426ccb537bb51363397e56cc7153f56391").into(), + hex!("f496b6f85a7c6c28a9048f2153550a7c5bcb4b23844ed3b87f6baa646124d8a3").into(), + hex!("7318644e474beb46e595a1875acc7444b937f5208065241911d2a71ac50c2de3").into(), + hex!("5cf48519e518ac64286aef5391319782dd38831d5dcc960578a6b9746d5f8cee").into(), + hex!("efb3e50fa39ca9fe7f76adbfa36fa8451ec2fd5d07b22aaf822137c04cf95a76").into(), + hex!("2206cd50750355ffaef4a67634c21168f2b564c58ffd04f33b0dc7af7dab3291").into(), + hex!("1a4014f6c4fcce9949fba74cb0f9e88df086706f9e05560cc9f0926f8c90e373").into(), + hex!("2df7cc0bcf3060be4132c63da7599c2600d9bbadf37ab001f15629bc2255698e").into(), + hex!("b7d05f875f140027ef5118a2247bbb84ce8f2f0f1123623085daf7960c329f5f").into(), + ], + finalized_block_root: hex!("f869dd1c9598043008a3ac2a5d91b3d6c7b0bb3295b3843bc84c083d70b0e604").into(), + }), + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("5d7859883dde1eba6c98b20eac18426134b25da2a89e5e360f3343b15e0e0a31").into(), + fee_recipient: hex!("0000000000000000000000000000000000000000").into(), + state_root: hex!("f8fbebed4c84d46231bd293bb9fbc9340d5c28c284d99fdaddb77238b8960ae2").into(), + receipts_root: hex!("f9d844c5b79638609ba385b910fec3b5d891c9d7b189f135f0432f33473de915").into(), + logs_bloom: hex!("00800000000000000000000020000000000000000000004000000000000000000400000000000000000000001000000010000000000000000000000008000000200000000000000001000008000000000000000000000000000000008000080000000000200000000000000000000000000100000000000000000011000000000000020200000000000000000000000000003000000040080008000000000000000000040044000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200800000000000").into(), + prev_randao: hex!("15533eeb366c6386bea5aeb8f425871928348c092209e4377f2418a6dedd7fd0").into(), + block_number: 2321, + gas_limit: 30000000, + gas_used: 113846, + timestamp: 1710554741, + extra_data: hex!("d983010d0b846765746888676f312e32312e368664617277696e").into(), + base_fee_per_gas: U256::from(7u64), + block_hash: hex!("585a07122a30339b03b6481eae67c2d3de2b6b64f9f426230986519bf0f1bdfe").into(), + transactions_root: hex!("09cd60ee2207d804397c81f7b7e1e5d3307712b136e5376623a80317a4bdcd7a").into(), + withdrawals_root: hex!("792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535").into(), + blob_gas_used: 0, + excess_blob_gas: 0, + }), + execution_branch: vec![ + hex!("9d419471a9a4719b40e7607781fbe32d9a7766b79805505c78c0c58133496ba2").into(), + hex!("b46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("bee375b8f1bbe4cd0e783c78026c1829ae72741c2dead5cab05d6834c5e5df65").into(), + ], + } }, }, + finalized_header: BeaconHeader { + slot: 4032, + proposer_index: 5, + parent_root: hex!("180aaaec59d38c3860e8af203f01f41c9bc41665f4d17916567c80f6cd23e8a2").into(), + state_root: hex!("3341790429ed3bf894cafa3004351d0b99e08baf6c38eb2a54d58e69fd2d19c6").into(), + body_root: hex!("a221e0c695ac7b7d04ce39b28b954d8a682ecd57961d81b44783527c6295f455").into(), + }, + block_roots_root: hex!("5744385ef06f82e67606f49aa29cd162f2e837a68fb7bd82f1fc6155d9f8640f").into(), } } diff --git a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token_to_penpal.rs b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token_to_penpal.rs index 86ba3f7ecc18..6a951b568ae5 100755 --- a/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token_to_penpal.rs +++ b/bridges/snowbridge/pallets/inbound-queue/fixtures/src/send_token_to_penpal.rs @@ -3,39 +3,93 @@ // Generated, do not edit! // See ethereum client README.md for instructions to generate -use crate::InboundQueueFixture; use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; +use snowbridge_beacon_primitives::{ + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; use sp_std::vec; pub fn make_send_token_to_penpal_message() -> InboundQueueFixture { InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("434148c290f27ee4be34fa344cd7608bf942a4541b27c9d868439631b3f37a8d").into(), - block_number: 816, - state_root: hex!("595e643f9095870e30e85e2bbef7d9e3a39df5aae839d26cf455d3dbf3e5a539").into(), - receipts_root: hex!("c40ab2c4abcfdea4f42195e0ad822806e5423108021c3b542646c7193319a6c1").into(), - }, message: Message { event_log: Log { address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), topics: vec![ hex!("7153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84f").into(), hex!("c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539").into(), - hex!("c8eaf22f2cb07bac4679df0a660e7115ed87fcfd4e32ac269f6540265bbbd26f").into(), + hex!("be323bced46a1a49c8da2ab62ad5e974fd50f1dabaeed70b23ca5bcf14bfe4aa").into(), ], - data: hex!("00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007300a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d01d00700001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c00286bee000000000000000000000000000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000000000000000000000000000").into(), + data: hex!("00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007300a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d01d00700001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c00286bee000000000000000000000000000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000000000000000000000000000").into(), }, proof: Proof { - block_hash: hex!("6c49a7f8fb2014a23e58a949c95a6743174589a7ce83434b073dc05dec402f3d").into(), - tx_index: 0, - data: (vec![ - hex!("c40ab2c4abcfdea4f42195e0ad822806e5423108021c3b542646c7193319a6c1").to_vec(), + receipt_proof: (vec![ + hex!("106f1eaeac04e469da0020ad5c8a72af66323638bd3f561a3c8236063202c120").to_vec(), ], vec![ - hex!("f90471822080b9046b02f90467018301d30fb9010000800000000000000000000000000000000000000000004000000000000000000400000000004000000000001000000010000000000000000000000008000000200000000000000001000008000000000000000000000000000000008000080000000000200000000000000000000000000100000000000000000011000000000000020000000000000000000000000000003000000000080018000000000000000000040044000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200820000000000f9035cf89b9487d1f7fdfee7f651fabc8bfcb6e086c278b77a7df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000057a2d4ff0c3866d96556884bf09fecdd7ccd530ca00000000000000000000000000000000000000000000000000de0b6b3a7640000f9015d94eda338e4dc46038493b885327842fd3e301cab39f884a024c5d2de620c6e25186ae16f6919eba93b6e2c1a33857cc419d9f3a00d6967e9a000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7da000000000000000000000000000000000000000000000000000000000000007d0b8c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000201cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07cf9015c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a0c8eaf22f2cb07bac4679df0a660e7115ed87fcfd4e32ac269f6540265bbbd26fb8e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007300a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d01d00700001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c00286bee000000000000000000000000000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000000000000000000000000000").to_vec(), + hex!("f90471822080b9046b02f904670183017d9cb9010000800000000000008000000000000000000000000000004000000000000000000400000000004000000000001000000010000000000000000000001008000000000000000000000001000008000040000000000000000000000000008000080000000000200000000000000000000000000100000000000000000010000000000000020000000000000000000000000000003000000000080018000000000000000000040004000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200820000000000f9035cf89b9487d1f7fdfee7f651fabc8bfcb6e086c278b77a7df863a0ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000057a2d4ff0c3866d96556884bf09fecdd7ccd530ca00000000000000000000000000000000000000000000000000de0b6b3a7640000f9015d94eda338e4dc46038493b885327842fd3e301cab39f884a024c5d2de620c6e25186ae16f6919eba93b6e2c1a33857cc419d9f3a00d6967e9a000000000000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7da000000000000000000000000090a987b944cb1dcce5564e5fdecd7a54d3de27fea000000000000000000000000000000000000000000000000000000000000007d0b8c000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000201cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07cf9015c94eda338e4dc46038493b885327842fd3e301cab39f863a07153f9357c8ea496bba60bf82e67143e27b64462b49041f8e689e1b05728f84fa0c173fac324158e77fb5840738a1a541f633cbec8884c6a601c567d2b376a0539a0be323bced46a1a49c8da2ab62ad5e974fd50f1dabaeed70b23ca5bcf14bfe4aab8e000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000007300a736aa00000000000187d1f7fdfee7f651fabc8bfcb6e086c278b77a7d01d00700001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c00286bee000000000000000000000000000064a7b3b6e00d000000000000000000e40b5402000000000000000000000000000000000000000000000000").to_vec(), ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: 4235, + proposer_index: 4, + parent_root: hex!("1b31e6264c19bcad120e434e0aede892e7d7c8ed80ab505cb593d9a4a16bc566").into(), + state_root: hex!("725f51771a0ecf72c647a283ab814ca088f998eb8c203181496b0b8e01f624fa").into(), + body_root: hex!("6f1c326d192e7e97e21e27b16fd7f000b8fa09b435ff028849927e382302b0ce").into(), + }, + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + hex!("1b31e6264c19bcad120e434e0aede892e7d7c8ed80ab505cb593d9a4a16bc566").into(), + hex!("335eb186c077fa7053ec96dcc5d34502c997713d2d5bc4eb74842118d8cd5a64").into(), + hex!("326607faf2a7dfc9cfc4b6895f8f3d92a659552deb2c8fd1e892ec00c86c734c").into(), + hex!("4e20002125d7b6504df7c774f3f48e018e1e6762d03489149670a8335bba1425").into(), + hex!("e76af5cd61aade5aec8282b6f1df9046efa756b0466bba5e49032410f7739a1b").into(), + hex!("ee4dcd9527712116380cddafd120484a3bedf867225bbb86850b84decf6da730").into(), + hex!("e4687a07421d3150439a2cd2f09f3b468145d75b359a2e5fa88dfbec51725b15").into(), + hex!("38eaa78978e95759aa9b6f8504a8dbe36151f20ae41907e6a1ea165700ceefcd").into(), + hex!("1c1b071ec6f13e15c47d07d1bfbcc9135d6a6c819e68e7e6078a2007418c1a23").into(), + hex!("0b3ad7ad193c691c8c4ba1606ad2a90482cd1d033c7db58cfe739d0e20431e9e").into(), + hex!("ffff0ad7e659772f9534c195c815efc4014ef1e1daed4404c06385d11192e92b").into(), + hex!("6cf04127db05441cd833107a52be852868890e4317e6a02ab47683aa75964220").into(), + hex!("b2ffec5f2c14640305dd941330f09216c53b99d198e93735a400a6d3a4de191f").into(), + ], + finalized_block_root: hex!("08be7a59e947f08cd95c4ef470758730bf9e3b0db0824cb663ea541c39b0e65c").into(), + }), + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("5d1186ae041f58785edb2f01248e95832f2e5e5d6c4eb8f7ff2f58980bfc2de9").into(), + fee_recipient: hex!("0000000000000000000000000000000000000000").into(), + state_root: hex!("2a66114d20e93082c8e9b47c8d401a937013487d757c9c2f3123cf43dc1f656d").into(), + receipts_root: hex!("106f1eaeac04e469da0020ad5c8a72af66323638bd3f561a3c8236063202c120").into(), + logs_bloom: hex!("00800000000000008000000000000000000000000000004000000000000000000400000000004000000000001000000010000000000000000000001008000000000000000000000001000008000040000000000000000000000000008000080000000000200000000000000000000000000100000000000000000010000000000000020000000000000000000000000000003000000000080018000000000000000000040004000021000000002000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000200820000000000").into(), + prev_randao: hex!("92e063c7e369b74149fdd1d7132ed2f635a19b9d8bff57637b8ee4736576426e").into(), + block_number: 4235, + gas_limit: 30000000, + gas_used: 97692, + timestamp: 1710556655, + extra_data: hex!("d983010d0b846765746888676f312e32312e368664617277696e").into(), + base_fee_per_gas: U256::from(7u64), + block_hash: hex!("ce24fe3047aa20a8f222cd1d04567c12b39455400d681141962c2130e690953f").into(), + transactions_root: hex!("0c8388731de94771777c60d452077065354d90d6e5088db61fc6a134684195cc").into(), + withdrawals_root: hex!("792930bbd5baac43bcc798ee49aa8185ef76bb3b44ba62b91d86ae569e4bb535").into(), + blob_gas_used: 0, + excess_blob_gas: 0, + }), + execution_branch: vec![ + hex!("99d397fa180078e66cd3a3b77bcb07553052f4e21d447167f3a406f663b14e6a").into(), + hex!("b46f0c01805fe212e15907981b757e6c496b0cb06664224655613dcec82505bb").into(), + hex!("db56114e00fdd4c1f85c892bf35ac9a89289aaecb1ebd0a96cde606a748b5d71").into(), + hex!("53ddf17147819c1abb918178b0230d965d1bc2c0d389f45e91e54cb1d2d468aa").into(), + ], + } }, }, + finalized_header: BeaconHeader { + slot: 4672, + proposer_index: 4, + parent_root: hex!("951233bf9f4bddfb2fa8f54e3bd0c7883779ef850e13e076baae3130dd7732db").into(), + state_root: hex!("4d303003b8cb097cbcc14b0f551ee70dac42de2c1cc2f4acfca7058ca9713291").into(), + body_root: hex!("664d13952b6f369bf4cf3af74d067ec33616eb57ed3a8a403fd5bae4fbf737dd").into(), + }, + block_roots_root: hex!("af71048297c070e6539cf3b9b90ae07d86d363454606bc239734629e6b49b983").into(), } } diff --git a/bridges/snowbridge/pallets/inbound-queue/src/benchmarking/mod.rs b/bridges/snowbridge/pallets/inbound-queue/src/benchmarking/mod.rs index 931befa2ac67..d59d92757721 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/benchmarking/mod.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/benchmarking/mod.rs @@ -19,8 +19,8 @@ mod benchmarks { let create_message = make_register_token_message(); T::Helper::initialize_storage( - create_message.message.proof.block_hash, - create_message.execution_header, + create_message.finalized_header, + create_message.block_roots_root, ); let sovereign_account = sibling_sovereign_account::(1000u32.into()); diff --git a/bridges/snowbridge/pallets/inbound-queue/src/lib.rs b/bridges/snowbridge/pallets/inbound-queue/src/lib.rs index b3b34cd96422..42fb30a09dae 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/lib.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/lib.rs @@ -28,9 +28,6 @@ mod envelope; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_beacon_primitives::CompactExecutionHeader; - pub mod weights; #[cfg(test)] @@ -73,6 +70,9 @@ use sp_runtime::{traits::Saturating, SaturatedConversion, TokenError}; pub use weights::WeightInfo; +#[cfg(feature = "runtime-benchmarks")] +use snowbridge_beacon_primitives::BeaconHeader; + type BalanceOf = <::Token as Inspect<::AccountId>>::Balance; @@ -92,7 +92,7 @@ pub mod pallet { #[cfg(feature = "runtime-benchmarks")] pub trait BenchmarkHelper { - fn initialize_storage(block_hash: H256, header: CompactExecutionHeader); + fn initialize_storage(beacon_header: BeaconHeader, block_roots_root: H256); } #[pallet::config] diff --git a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs index a641479080b4..cd6bdd0a943b 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/mock.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/mock.rs @@ -8,7 +8,9 @@ use frame_support::{ weights::IdentityFee, }; use hex_literal::hex; -use snowbridge_beacon_primitives::{Fork, ForkVersions}; +use snowbridge_beacon_primitives::{ + types::deneb, BeaconHeader, ExecutionProof, Fork, ForkVersions, VersionedExecutionPayloadHeader, +}; use snowbridge_core::{ gwei, inbound::{Log, Proof, VerificationError}, @@ -20,7 +22,7 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentifyAccount, IdentityLookup, Verify}, BuildStorage, FixedU128, MultiSignature, }; -use sp_std::convert::From; +use sp_std::{convert::From, default::Default}; use xcm::{latest::SendXcm, prelude::*}; use xcm_executor::AssetsInHolding; @@ -152,7 +154,7 @@ parameter_types! { #[cfg(feature = "runtime-benchmarks")] impl BenchmarkHelper for Test { // not implemented since the MockVerifier is used for tests - fn initialize_storage(_: H256, _: CompactExecutionHeader) {} + fn initialize_storage(_: BeaconHeader, _: H256) {} } // Mock XCM sender that always succeeds @@ -347,5 +349,32 @@ pub fn mock_event_log_invalid_gateway() -> Log { } } +pub fn mock_execution_proof() -> ExecutionProof { + ExecutionProof { + header: BeaconHeader::default(), + ancestry_proof: None, + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: Default::default(), + fee_recipient: Default::default(), + state_root: Default::default(), + receipts_root: Default::default(), + logs_bloom: vec![], + prev_randao: Default::default(), + block_number: 0, + gas_limit: 0, + gas_used: 0, + timestamp: 0, + extra_data: vec![], + base_fee_per_gas: Default::default(), + block_hash: Default::default(), + transactions_root: Default::default(), + withdrawals_root: Default::default(), + blob_gas_used: 0, + excess_blob_gas: 0, + }), + execution_branch: vec![], + } +} + pub const ASSET_HUB_PARAID: u32 = 1000u32; pub const TEMPLATE_PARAID: u32 = 1001u32; diff --git a/bridges/snowbridge/pallets/inbound-queue/src/test.rs b/bridges/snowbridge/pallets/inbound-queue/src/test.rs index 3c1016eed8b6..bd993c968df7 100644 --- a/bridges/snowbridge/pallets/inbound-queue/src/test.rs +++ b/bridges/snowbridge/pallets/inbound-queue/src/test.rs @@ -25,9 +25,8 @@ fn test_submit_happy_path() { let message = Message { event_log: mock_event_log(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; @@ -77,9 +76,8 @@ fn test_submit_xcm_invalid_channel() { let message = Message { event_log: mock_event_log_invalid_channel(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; assert_noop!( @@ -103,9 +101,8 @@ fn test_submit_with_invalid_gateway() { let message = Message { event_log: mock_event_log_invalid_gateway(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; assert_noop!( @@ -129,9 +126,8 @@ fn test_submit_with_invalid_nonce() { let message = Message { event_log: mock_event_log(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); @@ -163,9 +159,8 @@ fn test_submit_no_funds_to_reward_relayers_just_ignore() { let message = Message { event_log: mock_event_log(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; // Check submit successfully in case no funds available @@ -181,9 +176,8 @@ fn test_set_operating_mode() { let message = Message { event_log: mock_event_log(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; @@ -223,9 +217,8 @@ fn test_submit_no_funds_to_reward_relayers_and_ed_preserved() { let message = Message { event_log: mock_event_log(), proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); @@ -240,9 +233,8 @@ fn test_submit_no_funds_to_reward_relayers_and_ed_preserved() { let message = Message { event_log, proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), + receipt_proof: Default::default(), + execution_proof: mock_execution_proof(), }, }; assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); diff --git a/bridges/snowbridge/primitives/beacon/src/lib.rs b/bridges/snowbridge/primitives/beacon/src/lib.rs index 4c569d0176c2..6579d0f60966 100644 --- a/bridges/snowbridge/primitives/beacon/src/lib.rs +++ b/bridges/snowbridge/primitives/beacon/src/lib.rs @@ -15,12 +15,12 @@ pub mod updates; mod serde_utils; pub use types::{ - BeaconHeader, CompactBeaconState, CompactExecutionHeader, ExecutionHeaderState, - ExecutionPayloadHeader, FinalizedHeaderState, Fork, ForkData, ForkVersion, ForkVersions, Mode, - PublicKey, Signature, SigningData, SyncAggregate, SyncCommittee, SyncCommitteePrepared, + AncestryProof, BeaconHeader, CompactBeaconState, ExecutionPayloadHeader, ExecutionProof, + FinalizedHeaderState, Fork, ForkData, ForkVersion, ForkVersions, Mode, PublicKey, Signature, + SigningData, SyncAggregate, SyncCommittee, SyncCommitteePrepared, VersionedExecutionPayloadHeader, }; -pub use updates::{CheckpointUpdate, ExecutionHeaderUpdate, NextSyncCommitteeUpdate, Update}; +pub use updates::{CheckpointUpdate, NextSyncCommitteeUpdate, Update}; pub use bits::decompress_sync_committee_bits; pub use bls::{ diff --git a/bridges/snowbridge/primitives/beacon/src/types.rs b/bridges/snowbridge/primitives/beacon/src/types.rs index 6f0886ba8b5c..9a699a1755cc 100644 --- a/bridges/snowbridge/primitives/beacon/src/types.rs +++ b/bridges/snowbridge/primitives/beacon/src/types.rs @@ -110,14 +110,6 @@ impl<'de> Deserialize<'de> for Signature { } } -#[derive(Copy, Clone, 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(Copy, Clone, Default, Encode, Decode, TypeInfo, MaxEncodedLen)] pub struct FinalizedHeaderState { pub beacon_block_root: H256, @@ -346,35 +338,6 @@ impl ExecutionPayloadHeader { } } -#[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, - } - } -} - #[derive( Default, Encode, @@ -405,18 +368,6 @@ pub enum VersionedExecutionPayloadHeader { Deneb(deneb::ExecutionPayloadHeader), } -/// Convert VersionedExecutionPayloadHeader to CompactExecutionHeader -impl From for CompactExecutionHeader { - fn from(versioned_execution_header: VersionedExecutionPayloadHeader) -> Self { - match versioned_execution_header { - VersionedExecutionPayloadHeader::Capella(execution_payload_header) => - execution_payload_header.into(), - VersionedExecutionPayloadHeader::Deneb(execution_payload_header) => - execution_payload_header.into(), - } - } -} - impl VersionedExecutionPayloadHeader { pub fn hash_tree_root(&self) -> Result { match self { @@ -448,6 +399,45 @@ impl VersionedExecutionPayloadHeader { execution_payload_header.block_number, } } + + pub fn receipts_root(&self) -> H256 { + match self { + VersionedExecutionPayloadHeader::Capella(execution_payload_header) => + execution_payload_header.receipts_root, + VersionedExecutionPayloadHeader::Deneb(execution_payload_header) => + execution_payload_header.receipts_root, + } + } +} + +#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] +#[cfg_attr( + feature = "std", + derive(serde::Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +pub struct ExecutionProof { + /// Header for the beacon block containing the execution payload + pub header: BeaconHeader, + /// Proof that `header` is an ancestor of a finalized header + pub ancestry_proof: Option, + /// The execution header to be verified + pub execution_header: VersionedExecutionPayloadHeader, + /// Merkle proof that execution payload is contained within `header` + pub execution_branch: Vec, +} + +#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] +#[cfg_attr( + feature = "std", + derive(serde::Deserialize), + serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) +)] +pub struct AncestryProof { + /// Merkle proof that `header` is an ancestor of `finalized_header` + pub header_branch: Vec, + /// Root of a finalized block that has already been imported into the light client + pub finalized_block_root: H256, } #[cfg(test)] @@ -576,7 +566,6 @@ pub enum Mode { } pub mod deneb { - use crate::CompactExecutionHeader; use codec::{Decode, Encode}; use frame_support::{CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound}; use scale_info::TypeInfo; @@ -627,15 +616,4 @@ pub mod deneb { pub blob_gas_used: u64, // [New in Deneb:EIP4844] pub excess_blob_gas: u64, // [New in Deneb:EIP4844] } - - 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, - } - } - } } diff --git a/bridges/snowbridge/primitives/beacon/src/updates.rs b/bridges/snowbridge/primitives/beacon/src/updates.rs index 442d7565768f..ca651b5806f2 100644 --- a/bridges/snowbridge/primitives/beacon/src/updates.rs +++ b/bridges/snowbridge/primitives/beacon/src/updates.rs @@ -6,7 +6,7 @@ use scale_info::TypeInfo; use sp_core::H256; use sp_std::prelude::*; -use crate::types::{BeaconHeader, SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader}; +use crate::types::{BeaconHeader, SyncAggregate, SyncCommittee}; #[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] #[cfg_attr( @@ -65,33 +65,3 @@ pub struct NextSyncCommitteeUpdate { pub next_sync_committee: SyncCommittee, pub next_sync_committee_branch: Vec, } - -#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] -#[cfg_attr( - feature = "std", - derive(serde::Deserialize), - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -pub struct ExecutionHeaderUpdate { - /// Header for the beacon block containing the execution payload - pub header: BeaconHeader, - /// Proof that `header` is an ancestor of a finalized header - pub ancestry_proof: Option, - /// Execution header to be imported - pub execution_header: VersionedExecutionPayloadHeader, - /// Merkle proof that execution payload is contained within `header` - pub execution_branch: Vec, -} - -#[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, TypeInfo)] -#[cfg_attr( - feature = "std", - derive(serde::Deserialize), - serde(deny_unknown_fields, bound(serialize = ""), bound(deserialize = "")) -)] -pub struct AncestryProof { - /// Merkle proof that `header` is an ancestor of `finalized_header` - pub header_branch: Vec, - /// Root of a finalized block that has already been imported into the light client - pub finalized_block_root: H256, -} diff --git a/bridges/snowbridge/primitives/core/src/inbound.rs b/bridges/snowbridge/primitives/core/src/inbound.rs index 4b04470ad026..9e8ed789ab50 100644 --- a/bridges/snowbridge/primitives/core/src/inbound.rs +++ b/bridges/snowbridge/primitives/core/src/inbound.rs @@ -5,6 +5,7 @@ use codec::{Decode, Encode}; use frame_support::PalletError; use scale_info::TypeInfo; +use snowbridge_beacon_primitives::{BeaconHeader, ExecutionProof}; use sp_core::{H160, H256}; use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; @@ -25,6 +26,8 @@ pub enum VerificationError { InvalidLog, /// Unable to verify the transaction receipt with the provided proof InvalidProof, + /// Unable to verify the execution header with ancestry proof + InvalidExecutionProof(#[codec(skip)] &'static str), } pub type MessageNonce = u64; @@ -65,10 +68,15 @@ impl Log { /// Inclusion proof for a transaction receipt #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Proof { - // The block hash of the block in which the receipt was included. - pub block_hash: H256, - // The index of the transaction (and receipt) within the block. - pub tx_index: u32, // Proof keys and values (receipts tree) - pub data: (Vec>, Vec>), + pub receipt_proof: (Vec>, Vec>), + // Proof that an execution header was finalized by the beacon chain + pub execution_proof: ExecutionProof, +} + +#[derive(Clone, RuntimeDebug)] +pub struct InboundQueueFixture { + pub message: Message, + pub finalized_header: BeaconHeader, + pub block_roots_root: H256, } diff --git a/bridges/snowbridge/runtime/test-common/src/lib.rs b/bridges/snowbridge/runtime/test-common/src/lib.rs index 7455adf76170..3e2de0e481b8 100644 --- a/bridges/snowbridge/runtime/test-common/src/lib.rs +++ b/bridges/snowbridge/runtime/test-common/src/lib.rs @@ -467,7 +467,6 @@ pub fn ethereum_extrinsic( let initial_checkpoint = make_checkpoint(); let update = make_finalized_header_update(); let sync_committee_update = make_sync_committee_update(); - let execution_header_update = make_execution_header_update(); let alice = Alice; let alice_account = alice.to_account_id(); @@ -494,22 +493,12 @@ pub fn ethereum_extrinsic( } .into(); - let execution_header_call: ::RuntimeCall = - snowbridge_pallet_ethereum_client::Call::::submit_execution_header { - update: Box::new(*execution_header_update), - } - .into(); - let update_outcome = construct_and_apply_extrinsic(alice, update_call.into()); assert_ok!(update_outcome); let sync_committee_outcome = construct_and_apply_extrinsic(alice, update_sync_committee_call.into()); assert_ok!(sync_committee_outcome); - - let execution_header_outcome = - construct_and_apply_extrinsic(alice, execution_header_call.into()); - assert_ok!(execution_header_outcome); }); } @@ -548,7 +537,6 @@ pub fn ethereum_to_polkadot_message_extrinsics_work( .execute_with(|| { let initial_checkpoint = make_checkpoint(); let sync_committee_update = make_sync_committee_update(); - let execution_header_update = make_execution_header_update(); let alice = Alice; let alice_account = alice.to_account_id(); @@ -569,18 +557,8 @@ pub fn ethereum_to_polkadot_message_extrinsics_work( } .into(); - let execution_header_call: ::RuntimeCall = - snowbridge_pallet_ethereum_client::Call::::submit_execution_header { - update: Box::new(*execution_header_update), - } - .into(); - let sync_committee_outcome = construct_and_apply_extrinsic(alice, update_sync_committee_call.into()); assert_ok!(sync_committee_outcome); - - let execution_header_outcome = - construct_and_apply_extrinsic(alice, execution_header_call.into()); - assert_ok!(execution_header_outcome); }); } diff --git a/bridges/snowbridge/templates/benchmarking-fixtures.mustache b/bridges/snowbridge/templates/beacon-fixtures.mustache similarity index 60% rename from bridges/snowbridge/templates/benchmarking-fixtures.mustache rename to bridges/snowbridge/templates/beacon-fixtures.mustache index abeab79a5326..5942be056321 100644 --- a/bridges/snowbridge/templates/benchmarking-fixtures.mustache +++ b/bridges/snowbridge/templates/beacon-fixtures.mustache @@ -1,16 +1,24 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork // Generated, do not edit! // See README.md for instructions to generate -use crate::{ - CheckpointUpdate, ExecutionHeaderUpdate, Update, -}; +#![cfg_attr(not(feature = "std"), no_std)] + use hex_literal::hex; -use primitives::{ - types::deneb, updates::AncestryProof, BeaconHeader, NextSyncCommitteeUpdate, SyncAggregate, - SyncCommittee, VersionedExecutionPayloadHeader, +use snowbridge_beacon_primitives::{ + types::deneb, AncestryProof, BeaconHeader, ExecutionProof, NextSyncCommitteeUpdate, + SyncAggregate, SyncCommittee, VersionedExecutionPayloadHeader, }; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; use sp_core::U256; use sp_std::{boxed::Box, vec}; +const SC_SIZE: usize = 512; +const SC_BITS_SIZE: usize = 64; +type CheckpointUpdate = snowbridge_beacon_primitives::CheckpointUpdate; +type Update = snowbridge_beacon_primitives::Update; + + pub fn make_checkpoint() -> Box { Box::new(CheckpointUpdate { header: BeaconHeader { @@ -129,8 +137,8 @@ pub fn make_finalized_header_update() -> Box { }) } -pub fn make_execution_header_update() -> Box { - Box::new(ExecutionHeaderUpdate { +pub fn make_execution_proof() -> Box { + Box::new(ExecutionProof { header: BeaconHeader { slot: {{HeaderUpdate.Header.Slot}}, proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, @@ -165,7 +173,7 @@ pub fn make_execution_header_update() -> Box { extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), - transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionRoot}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, @@ -177,3 +185,86 @@ pub fn make_execution_header_update() -> Box { ], }) } + +pub fn make_inbound_fixture() -> InboundQueueFixture { + InboundQueueFixture { + message: Message { + event_log: Log { + address: hex!("{{InboundMessage.EventLog.Address}}").into(), + topics: vec![ + {{#InboundMessage.EventLog.Topics}} + hex!("{{.}}").into(), + {{/InboundMessage.EventLog.Topics}} + ], + data: hex!("{{InboundMessage.EventLog.Data}}").into(), + }, + proof: Proof { + block_hash: hex!("{{InboundMessage.Proof.BlockHash}}").into(), + tx_index: {{InboundMessage.Proof.TxIndex}}, + receipt_proof: (vec![ + {{#InboundMessage.Proof.ReceiptProof.Keys}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Keys}} + ], vec![ + {{#InboundMessage.Proof.ReceiptProof.Values}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Values}} + ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: {{HeaderUpdate.Header.Slot}}, + proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{HeaderUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{HeaderUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{HeaderUpdate.Header.BodyRoot}}").into(), + }, + {{#HeaderUpdate.AncestryProof}} + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + {{#HeaderUpdate.AncestryProof.HeaderBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.AncestryProof.HeaderBranch}} + ], + finalized_block_root: hex!("{{HeaderUpdate.AncestryProof.FinalizedBlockRoot}}").into(), + }), + {{/HeaderUpdate.AncestryProof}} + {{^HeaderUpdate.AncestryProof}} + ancestry_proof: None, + {{/HeaderUpdate.AncestryProof}} + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ParentHash}}").into(), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.FeeRecipient}}").into(), + state_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.StateRoot}}").into(), + receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ReceiptsRoot}}").into(), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.LogsBloom}}").into(), + prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.PrevRandao}}").into(), + block_number: {{HeaderUpdate.ExecutionHeader.Deneb.BlockNumber}}, + gas_limit: {{HeaderUpdate.ExecutionHeader.Deneb.GasLimit}}, + gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.GasUsed}}, + timestamp: {{HeaderUpdate.ExecutionHeader.Deneb.Timestamp}}, + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), + base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), + block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), + withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), + blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, + excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, + }), + execution_branch: vec![ + {{#HeaderUpdate.ExecutionBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.ExecutionBranch}} + ], + } + }, + }, + finalized_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.FinalizedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), + } +} diff --git a/bridges/snowbridge/templates/inbound-fixtures.mustache b/bridges/snowbridge/templates/inbound-fixtures.mustache new file mode 100644 index 000000000000..b35a263fda02 --- /dev/null +++ b/bridges/snowbridge/templates/inbound-fixtures.mustache @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: Apache-2.0 +// SPDX-FileCopyrightText: 2023 Snowfork +// Generated, do not edit! +// See ethereum client README.md for instructions to generate + +use hex_literal::hex; +use snowbridge_beacon_primitives::{ +types::deneb, AncestryProof, BeaconHeader, ExecutionProof, VersionedExecutionPayloadHeader, +}; +use snowbridge_core::inbound::{InboundQueueFixture, Log, Message, Proof}; +use sp_core::U256; +use sp_std::vec; + +pub fn make_{{TestCase}}_message() -> InboundQueueFixture { + InboundQueueFixture { + message: Message { + event_log: Log { + address: hex!("{{InboundMessage.EventLog.Address}}").into(), + topics: vec![ + {{#InboundMessage.EventLog.Topics}} + hex!("{{.}}").into(), + {{/InboundMessage.EventLog.Topics}} + ], + data: hex!("{{InboundMessage.EventLog.Data}}").into(), + }, + proof: Proof { + block_hash: hex!("{{InboundMessage.Proof.BlockHash}}").into(), + tx_index: {{InboundMessage.Proof.TxIndex}}, + receipt_proof: (vec![ + {{#InboundMessage.Proof.ReceiptProof.Keys}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Keys}} + ], vec![ + {{#InboundMessage.Proof.ReceiptProof.Values}} + hex!("{{.}}").to_vec(), + {{/InboundMessage.Proof.ReceiptProof.Values}} + ]), + execution_proof: ExecutionProof { + header: BeaconHeader { + slot: {{HeaderUpdate.Header.Slot}}, + proposer_index: {{HeaderUpdate.Header.ProposerIndex}}, + parent_root: hex!("{{HeaderUpdate.Header.ParentRoot}}").into(), + state_root: hex!("{{HeaderUpdate.Header.StateRoot}}").into(), + body_root: hex!("{{HeaderUpdate.Header.BodyRoot}}").into(), + }, + {{#HeaderUpdate.AncestryProof}} + ancestry_proof: Some(AncestryProof { + header_branch: vec![ + {{#HeaderUpdate.AncestryProof.HeaderBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.AncestryProof.HeaderBranch}} + ], + finalized_block_root: hex!("{{HeaderUpdate.AncestryProof.FinalizedBlockRoot}}").into(), + }), + {{/HeaderUpdate.AncestryProof}} + {{^HeaderUpdate.AncestryProof}} + ancestry_proof: None, + {{/HeaderUpdate.AncestryProof}} + execution_header: VersionedExecutionPayloadHeader::Deneb(deneb::ExecutionPayloadHeader { + parent_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ParentHash}}").into(), + fee_recipient: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.FeeRecipient}}").into(), + state_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.StateRoot}}").into(), + receipts_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ReceiptsRoot}}").into(), + logs_bloom: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.LogsBloom}}").into(), + prev_randao: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.PrevRandao}}").into(), + block_number: {{HeaderUpdate.ExecutionHeader.Deneb.BlockNumber}}, + gas_limit: {{HeaderUpdate.ExecutionHeader.Deneb.GasLimit}}, + gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.GasUsed}}, + timestamp: {{HeaderUpdate.ExecutionHeader.Deneb.Timestamp}}, + extra_data: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.ExtraData}}").into(), + base_fee_per_gas: U256::from({{HeaderUpdate.ExecutionHeader.Deneb.BaseFeePerGas}}u64), + block_hash: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.BlockHash}}").into(), + transactions_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.TransactionsRoot}}").into(), + withdrawals_root: hex!("{{HeaderUpdate.ExecutionHeader.Deneb.WithdrawalsRoot}}").into(), + blob_gas_used: {{HeaderUpdate.ExecutionHeader.Deneb.BlobGasUsed}}, + excess_blob_gas: {{HeaderUpdate.ExecutionHeader.Deneb.ExcessBlobGas}}, + }), + execution_branch: vec![ + {{#HeaderUpdate.ExecutionBranch}} + hex!("{{.}}").into(), + {{/HeaderUpdate.ExecutionBranch}} + ], + } + }, + }, + finalized_header: BeaconHeader { + slot: {{FinalizedHeaderUpdate.FinalizedHeader.Slot}}, + proposer_index: {{FinalizedHeaderUpdate.FinalizedHeader.ProposerIndex}}, + parent_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.ParentRoot}}").into(), + state_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.StateRoot}}").into(), + body_root: hex!("{{FinalizedHeaderUpdate.FinalizedHeader.BodyRoot}}").into(), + }, + block_roots_root: hex!("{{FinalizedHeaderUpdate.BlockRootsRoot}}").into(), + } +} diff --git a/bridges/snowbridge/templates/register_token.mustache b/bridges/snowbridge/templates/register_token.mustache deleted file mode 100644 index e8d35be42ec1..000000000000 --- a/bridges/snowbridge/templates/register_token.mustache +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork -// Generated, do not edit! -// See ethereum client README.md for instructions to generate - -use crate::InboundQueueFixture; -use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; -use sp_std::vec; - -pub fn make_register_token_message() -> InboundQueueFixture { - InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("{{InboundMessageTest.ExecutionHeader.ParentHash}}").into(), - block_number: {{InboundMessageTest.ExecutionHeader.BlockNumber}}, - state_root: hex!("{{InboundMessageTest.ExecutionHeader.StateRoot}}").into(), - receipts_root: hex!("{{InboundMessageTest.ExecutionHeader.ReceiptsRoot}}").into(), - }, - message: Message { - event_log: Log { - address: hex!("{{InboundMessageTest.Message.EventLog.Address}}").into(), - topics: vec![ - {{#InboundMessageTest.Message.EventLog.Topics}} - hex!("{{.}}").into(), - {{/InboundMessageTest.Message.EventLog.Topics}} - ], - data: hex!("{{InboundMessageTest.Message.EventLog.Data}}").into(), - }, - proof: Proof { - block_hash: hex!("{{InboundMessageTest.Message.Proof.BlockHash}}").into(), - tx_index: {{InboundMessageTest.Message.Proof.TxIndex}}, - data: (vec![ - {{#InboundMessageTest.Message.Proof.Data.Keys}} - hex!("{{.}}").to_vec(), - {{/InboundMessageTest.Message.Proof.Data.Keys}} - ], vec![ - {{#InboundMessageTest.Message.Proof.Data.Values}} - hex!("{{.}}").to_vec(), - {{/InboundMessageTest.Message.Proof.Data.Values}} - ]), - }, - }, - } -} diff --git a/bridges/snowbridge/templates/send_token.mustache b/bridges/snowbridge/templates/send_token.mustache deleted file mode 100644 index e104d2da279d..000000000000 --- a/bridges/snowbridge/templates/send_token.mustache +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// SPDX-FileCopyrightText: 2023 Snowfork -// Generated, do not edit! -// See ethereum client README.md for instructions to generate - -use crate::InboundQueueFixture; -use hex_literal::hex; -use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Log, Message, Proof}; -use sp_std::vec; - -pub fn make_send_token_message() -> InboundQueueFixture { - InboundQueueFixture { - execution_header: CompactExecutionHeader{ - parent_hash: hex!("{{InboundMessageTest.ExecutionHeader.ParentHash}}").into(), - block_number: {{InboundMessageTest.ExecutionHeader.BlockNumber}}, - state_root: hex!("{{InboundMessageTest.ExecutionHeader.StateRoot}}").into(), - receipts_root: hex!("{{InboundMessageTest.ExecutionHeader.ReceiptsRoot}}").into(), - }, - message: Message { - event_log: Log { - address: hex!("{{InboundMessageTest.Message.EventLog.Address}}").into(), - topics: vec![ - {{#InboundMessageTest.Message.EventLog.Topics}} - hex!("{{.}}").into(), - {{/InboundMessageTest.Message.EventLog.Topics}} - ], - data: hex!("{{InboundMessageTest.Message.EventLog.Data}}").into(), - }, - proof: Proof { - block_hash: hex!("{{InboundMessageTest.Message.Proof.BlockHash}}").into(), - tx_index: {{InboundMessageTest.Message.Proof.TxIndex}}, - data: (vec![ - {{#InboundMessageTest.Message.Proof.Data.Keys}} - hex!("{{.}}").to_vec(), - {{/InboundMessageTest.Message.Proof.Data.Keys}} - ], vec![ - {{#InboundMessageTest.Message.Proof.Data.Values}} - hex!("{{.}}").to_vec(), - {{/InboundMessageTest.Message.Proof.Data.Values}} - ]), - }, - }, - } -} diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs index 61df39b310de..543536e68982 100644 --- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs +++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/snowbridge.rs @@ -19,15 +19,15 @@ use emulated_integration_tests_common::xcm_emulator::ConvertLocation; use frame_support::pallet_prelude::TypeInfo; use hex_literal::hex; use rococo_westend_system_emulated_network::BridgeHubRococoParaSender as BridgeHubRococoSender; -use snowbridge_core::outbound::OperatingMode; +use snowbridge_core::{inbound::InboundQueueFixture, outbound::OperatingMode}; use snowbridge_pallet_inbound_queue_fixtures::{ - register_token::make_register_token_message, - register_token_with_insufficient_fee::make_register_token_with_infufficient_fee_message, - send_token::make_send_token_message, send_token_to_penpal::make_send_token_to_penpal_message, - InboundQueueFixture, + register_token::make_register_token_message, send_token::make_send_token_message, + send_token_to_penpal::make_send_token_to_penpal_message, }; use snowbridge_pallet_system; -use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor; +use snowbridge_router_primitives::inbound::{ + Command, GlobalConsensusEthereumConvertsFor, MessageV1, VersionedMessage, +}; use sp_core::H256; use sp_runtime::{DispatchError::Token, TokenError::FundsUnavailable}; use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork; @@ -38,6 +38,7 @@ const TREASURY_ACCOUNT: [u8; 32] = hex!("6d6f646c70792f74727372790000000000000000000000000000000000000000"); const WETH: [u8; 20] = hex!("87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d"); const ETHEREUM_DESTINATION_ADDRESS: [u8; 20] = hex!("44a57ee2f2FCcb85FDa2B0B18EBD0D8D2333700e"); +const INSUFFICIENT_XCM_FEE: u128 = 1000; #[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)] pub enum ControlCall { @@ -55,11 +56,11 @@ pub enum SnowbridgeControl { } pub fn send_inbound_message(fixture: InboundQueueFixture) -> DispatchResult { - EthereumBeaconClient::store_execution_header( - fixture.message.proof.block_hash, - fixture.execution_header, - ); - + EthereumBeaconClient::store_finalized_header( + fixture.finalized_header, + fixture.block_roots_root, + ) + .unwrap(); EthereumInboundQueue::submit( RuntimeOrigin::signed(BridgeHubRococoSender::get()), fixture.message, @@ -234,6 +235,46 @@ fn register_weth_token_from_ethereum_to_asset_hub() { }); } +/// Tests the registering of a token as an asset on AssetHub, and then subsequently sending +/// a token from Ethereum to AssetHub. +#[test] +fn send_token_from_ethereum_to_asset_hub() { + BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND); + + // Fund ethereum sovereign on AssetHub + AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]); + + BridgeHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // Construct RegisterToken message and sent to inbound queue + send_inbound_message(make_register_token_message()).unwrap(); + + // Construct SendToken message and sent to inbound queue + send_inbound_message(make_send_token_message()).unwrap(); + + // Check that the message was sent + assert_expected_events!( + BridgeHubRococo, + vec![ + RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, + ] + ); + }); + + AssetHubRococo::execute_with(|| { + type RuntimeEvent = ::RuntimeEvent; + + // Check that the token was received and issued as a foreign asset on AssetHub + assert_expected_events!( + AssetHubRococo, + vec![ + RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, + ] + ); + }); +} + /// Tests sending a token to a 3rd party parachain, called PenPal. The token reserve is /// still located on AssetHub. #[test] @@ -283,6 +324,10 @@ fn send_token_from_ethereum_to_penpal() { // Construct RegisterToken message and sent to inbound queue send_inbound_message(make_register_token_message()).unwrap(); + // Construct SendToken message to AssetHub(only for increase the nonce as the same order in + // smoke test) + send_inbound_message(make_send_token_message()).unwrap(); + // Construct SendToken message and sent to inbound queue send_inbound_message(make_send_token_to_penpal_message()).unwrap(); @@ -318,46 +363,6 @@ fn send_token_from_ethereum_to_penpal() { }); } -/// Tests the registering of a token as an asset on AssetHub, and then subsequently sending -/// a token from Ethereum to AssetHub. -#[test] -fn send_token_from_ethereum_to_asset_hub() { - BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND); - - // Fund ethereum sovereign on AssetHub - AssetHubRococo::fund_accounts(vec![(AssetHubRococoReceiver::get(), INITIAL_FUND)]); - - BridgeHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - // Construct RegisterToken message and sent to inbound queue - send_inbound_message(make_register_token_message()).unwrap(); - - // Construct SendToken message and sent to inbound queue - send_inbound_message(make_send_token_message()).unwrap(); - - // Check that the message was sent - assert_expected_events!( - BridgeHubRococo, - vec![ - RuntimeEvent::XcmpQueue(cumulus_pallet_xcmp_queue::Event::XcmpMessageSent { .. }) => {}, - ] - ); - }); - - AssetHubRococo::execute_with(|| { - type RuntimeEvent = ::RuntimeEvent; - - // Check that the token was received and issued as a foreign asset on AssetHub - assert_expected_events!( - AssetHubRococo, - vec![ - RuntimeEvent::ForeignAssets(pallet_assets::Event::Issued { .. }) => {}, - ] - ); - }); -} - /// Tests the full cycle of token transfers: /// - registering a token on AssetHub /// - sending a token to AssetHub @@ -493,16 +498,35 @@ fn send_weth_asset_from_asset_hub_to_ethereum() { }); } +#[test] +fn send_token_from_ethereum_to_asset_hub_fail_for_insufficient_fund() { + // Insufficient fund + BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), 1_000); + + BridgeHubRococo::execute_with(|| { + assert_err!(send_inbound_message(make_register_token_message()), Token(FundsUnavailable)); + }); +} + #[test] fn register_weth_token_in_asset_hub_fail_for_insufficient_fee() { BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), INITIAL_FUND); BridgeHubRococo::execute_with(|| { type RuntimeEvent = ::RuntimeEvent; - - // Construct RegisterToken message and sent to inbound queue - let message = make_register_token_with_infufficient_fee_message(); - send_inbound_message(message).unwrap(); + type EthereumInboundQueue = + ::EthereumInboundQueue; + let message_id: H256 = [0; 32].into(); + let message = VersionedMessage::V1(MessageV1 { + chain_id: CHAIN_ID, + command: Command::RegisterToken { + token: WETH.into(), + // Insufficient fee which should trigger the trap + fee: INSUFFICIENT_XCM_FEE, + }, + }); + let (xcm, _) = EthereumInboundQueue::do_convert(message_id, message).unwrap(); + let _ = EthereumInboundQueue::send_xcm(xcm, AssetHubRococo::para_id().into()).unwrap(); assert_expected_events!( BridgeHubRococo, @@ -523,13 +547,3 @@ fn register_weth_token_in_asset_hub_fail_for_insufficient_fee() { ); }); } - -#[test] -fn send_token_from_ethereum_to_asset_hub_fail_for_insufficient_fund() { - // Insufficient fund - BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), 1_000); - - BridgeHubRococo::execute_with(|| { - assert_err!(send_inbound_message(make_register_token_message()), Token(FundsUnavailable)); - }); -} diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs index daeff8f24ec4..b68bea512369 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs @@ -511,14 +511,14 @@ parameter_types! { pub mod benchmark_helpers { use crate::{EthereumBeaconClient, Runtime, RuntimeOrigin}; use codec::Encode; - use snowbridge_beacon_primitives::CompactExecutionHeader; + use snowbridge_beacon_primitives::BeaconHeader; use snowbridge_pallet_inbound_queue::BenchmarkHelper; use sp_core::H256; use xcm::latest::{Assets, Location, SendError, SendResult, SendXcm, Xcm, XcmHash}; impl BenchmarkHelper for Runtime { - fn initialize_storage(block_hash: H256, header: CompactExecutionHeader) { - EthereumBeaconClient::store_execution_header(block_hash, header) + fn initialize_storage(beacon_header: BeaconHeader, block_roots_root: H256) { + EthereumBeaconClient::store_finalized_header(beacon_header, block_roots_root).unwrap(); } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs index 0d5f29c6ff2f..c8017939b627 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_ethereum_client.rs @@ -126,26 +126,4 @@ impl snowbridge_pallet_ethereum_client::WeightInfo for .saturating_add(T::DbWeight::get().reads(6)) .saturating_add(T::DbWeight::get().writes(1)) } - /// Storage: EthereumBeaconClient LatestFinalizedBlockRoot (r:1 w:0) - /// Proof: EthereumBeaconClient LatestFinalizedBlockRoot (max_values: Some(1), max_size: Some(32), added: 527, mode: MaxEncodedLen) - /// Storage: EthereumBeaconClient FinalizedBeaconState (r:1 w:0) - /// Proof: EthereumBeaconClient FinalizedBeaconState (max_values: None, max_size: Some(72), added: 2547, mode: MaxEncodedLen) - /// Storage: EthereumBeaconClient LatestExecutionState (r:1 w:1) - /// Proof: EthereumBeaconClient LatestExecutionState (max_values: Some(1), max_size: Some(80), added: 575, mode: MaxEncodedLen) - /// Storage: EthereumBeaconClient ExecutionHeaderIndex (r:1 w:1) - /// Proof: EthereumBeaconClient ExecutionHeaderIndex (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) - /// Storage: EthereumBeaconClient ExecutionHeaderMapping (r:1 w:1) - /// Proof: EthereumBeaconClient ExecutionHeaderMapping (max_values: None, max_size: Some(36), added: 2511, mode: MaxEncodedLen) - /// Storage: EthereumBeaconClient ExecutionHeaders (r:0 w:1) - /// Proof: EthereumBeaconClient ExecutionHeaders (max_values: None, max_size: Some(136), added: 2611, mode: MaxEncodedLen) - fn submit_execution_header() -> Weight { - // Proof Size summary in bytes: - // Measured: `386` - // Estimated: `3537` - // Minimum execution time: 108_761_000 picoseconds. - Weight::from_parts(113_158_000, 0) - .saturating_add(Weight::from_parts(0, 3537)) - .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(4)) - } } diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs index faf404f90cb3..153c1d363be1 100644 --- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs +++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/weights/snowbridge_pallet_inbound_queue.rs @@ -58,12 +58,12 @@ impl snowbridge_pallet_inbound_queue::WeightInfo for We /// Proof: System Account (max_values: None, max_size: Some(128), added: 2603, mode: MaxEncodedLen) fn submit() -> Weight { // Proof Size summary in bytes: - // Measured: `457` - // Estimated: `3601` - // Minimum execution time: 69_000_000 picoseconds. - Weight::from_parts(70_000_000, 0) - .saturating_add(Weight::from_parts(0, 3601)) - .saturating_add(T::DbWeight::get().reads(4)) - .saturating_add(T::DbWeight::get().writes(2)) + // Measured: `800` + // Estimated: `7200` + // Minimum execution time: 200_000_000 picoseconds. + Weight::from_parts(200_000_000, 0) + .saturating_add(Weight::from_parts(0, 7200)) + .saturating_add(T::DbWeight::get().reads(9)) + .saturating_add(T::DbWeight::get().writes(6)) } }