From 1c33345737aedc9adc4836a35e75f9a02868f61c Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 2 Oct 2024 10:58:17 +0200 Subject: [PATCH 01/31] feat(fuel-integratin): initial integration --- rust/main/Cargo.lock | 108 +-- rust/main/Cargo.toml | 4 +- rust/main/chains/hyperlane-fuel/Cargo.toml | 1 + .../abis/AggregationISM.abi.json | 559 ++++++++++++ .../abis/InterchainGasPaymaster.abi.json | 709 ++++++++++++++++ .../abis/InterchainSecurityModule.abi.json | 346 ++++++++ .../hyperlane-fuel/abis/Mailbox.abi.json | 801 +++++++----------- .../abis/MerkleTreeHook.abi.json | 409 +++++++++ .../hyperlane-fuel/abis/MultisigISM.abi.json | 346 ++++++++ .../hyperlane-fuel/abis/RoutingISM.abi.json | 627 ++++++++++++++ .../abis/ValidatorAnnounce.abi.json | 483 +++++++++++ .../hyperlane-fuel/src/aggregation_ism.rs | 77 ++ .../chains/hyperlane-fuel/src/conversions.rs | 103 ++- .../main/chains/hyperlane-fuel/src/indexer.rs | 333 ++++++++ .../hyperlane-fuel/src/interchain_gas.rs | 171 +++- .../src/interchain_security_module.rs | 84 ++ rust/main/chains/hyperlane-fuel/src/lib.rs | 7 +- .../main/chains/hyperlane-fuel/src/mailbox.rs | 101 ++- .../hyperlane-fuel/src/merkle_tree_hook.rs | 241 ++++++ .../chains/hyperlane-fuel/src/multisig_ism.rs | 53 +- .../chains/hyperlane-fuel/src/provider.rs | 248 +----- .../chains/hyperlane-fuel/src/routing_ism.rs | 53 +- .../hyperlane-fuel/src/trait_builder.rs | 3 +- .../hyperlane-fuel/src/validator_announce.rs | 117 ++- .../src/contract_sync/cursors/mod.rs | 8 +- .../hyperlane-base/src/settings/chains.rs | 116 ++- .../src/settings/parser/connection_parser.rs | 10 +- .../hyperlane-base/src/settings/signers.rs | 2 +- rust/main/hyperlane-core/src/chain.rs | 7 +- 29 files changed, 5270 insertions(+), 857 deletions(-) create mode 100644 rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json create mode 100644 rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index d6f99c4890..d983642b35 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -3315,9 +3315,9 @@ checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" [[package]] name = "fuel-abi-types" -version = "0.5.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0e7e87f94417ff1a5d60e496906033c58bfe5367546621f131fe8cdabaa2671" +checksum = "bce44ac13b1971be7cea024a2003cf944522093dafec454fea9ff792f0ff2577" dependencies = [ "itertools 0.10.5", "lazy_static", @@ -3332,9 +3332,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "491f1777538b0e1d479609d0d75bca5242c7fd3394f2ddd4ea55b8c96bcc8387" +checksum = "711b83807968cd62babe6cd70c94b76c86f302c8573da18b3c69135688eceecd" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -3344,9 +3344,9 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05c13f888fb9b705b64bbcb56d022345cf85a86535d646bf53e20771eb4b986a" +checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" dependencies = [ "anyhow", "bech32 0.9.1", @@ -3364,9 +3364,9 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1910fce3eebe33b5acba656e092e5ede267acb4b1c3f17c122a0477270091" +checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" dependencies = [ "anyhow", "cynic", @@ -3388,9 +3388,9 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1e2f22f6c4ce2696c29c14083c465f276c8d8eca67f051cb7d09a72442ceb5e" +checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" dependencies = [ "parking_lot 0.12.3", "pin-project-lite", @@ -3401,9 +3401,9 @@ dependencies = [ [[package]] name = "fuel-core-poa" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c646e9246bc333e365d130f5a854fb9c33f9237e178d87c75a7d136d1f3211f9" +checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" dependencies = [ "anyhow", "async-trait", @@ -3411,6 +3411,8 @@ dependencies = [ "fuel-core-services", "fuel-core-storage", "fuel-core-types", + "serde", + "serde_json", "tokio", "tokio-stream", "tracing", @@ -3418,9 +3420,9 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff8a175199e0e7b1373ac10d45eb26563c1e8299298c9589ab60efb1c7cae6ac" +checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" dependencies = [ "anyhow", "async-trait", @@ -3433,9 +3435,9 @@ dependencies = [ [[package]] name = "fuel-core-storage" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3ee3b462cc9b7e62b3ae04d5e3b792e6742c479bd75d6bc0987443a92b5299" +checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -3455,9 +3457,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.31.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "615783f63b40075d1bf64a42b4fd4edce076458c94b0fab2278a570b2b7a8e0e" +checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" dependencies = [ "anyhow", "bs58 0.5.1", @@ -3468,15 +3470,14 @@ dependencies = [ "secrecy", "serde", "tai64", - "thiserror", "zeroize", ] [[package]] name = "fuel-crypto" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f74f03ba9b27f375a0482b1afe20d5b8cfd032fedba683a584cdbd6d10147439" +checksum = "e5a4ca62d0a8a361b66a6eab3456285883d0aa92c407e249fc76f195c332fbb2" dependencies = [ "coins-bip32 0.8.7", "coins-bip39 0.8.7", @@ -3495,9 +3496,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ad30ad1a11e5a811ae67b6b0cb6785ce21bcd5ef0afd442fd963d5be95d09d" +checksum = "9ca99d9c264fec231a01e55bbdb6adb3080266dc44c4cc88de870b089ee2a015" dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", @@ -3507,9 +3508,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5433c41ffbf531eed1380148cd68e37f9dd7e25966a9c59518f6b09e346e80e2" +checksum = "02f3c08f22f7c24170a4ac255e7dfe52d52ae2e85c4a8e26ed6df4f1bd380210" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -3522,15 +3523,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce3fc3cd96fe312442cdf35966b96d66becd02582b505f856f74953f57adf020" +checksum = "d676ea5d926bf90c8ea442e5f6fc23c0e86c2e4d663f303842b4afe5b7928084" [[package]] name = "fuel-tx" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e00cc42ae3121b1881a6ae8306696d1bea73adca424216d9f676ee91d3927c74" +checksum = "86158d08fe2a936ac765a1e2cb9bf60be704203b3085882e7cc6cd4c48de38ef" dependencies = [ "bitflags 2.6.0", "derivative", @@ -3551,9 +3552,9 @@ dependencies = [ [[package]] name = "fuel-types" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae98e143dec4e6cb114a92435e314f1d4815e17e8fded24332fb285319d60167" +checksum = "42b4430c6a20669fffd8f2c17d2be6809a356f623243a78b5eedf8ba7897c036" dependencies = [ "fuel-derive", "hex 0.4.3", @@ -3563,9 +3564,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.55.0" +version = "0.57.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "641a2ee5a3398633fa243fba3343cbe2225ae335a09141f6b94041720cfc3520" +checksum = "b1b04a4e971d58b3662ff8b84b3176094e25f4b372728a13ea903fdf79c7e426" dependencies = [ "anyhow", "async-trait", @@ -3597,9 +3598,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601ed66a0485065471cd9c8bab2db7cfa58bc7ed5d2e68bd26fc573ac2575827" +checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3613,9 +3614,9 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed97e653906fe0bc60b5d7a7421f3c5fe766f516b762def8f4ccac707ac4bc3" +checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" dependencies = [ "async-trait", "chrono", @@ -3638,9 +3639,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edef30656b740ca9c279a7bcfe9e366557c271a2751e36316f780f18dc99c85" +checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" dependencies = [ "Inflector", "fuel-abi-types", @@ -3654,9 +3655,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff741c9f1ba2c701b50c76a98a5655d8bc0f275f7ae2dd0e724f8fc36eeb8a9f" +checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" dependencies = [ "async-trait", "bech32 0.9.1", @@ -3682,9 +3683,9 @@ dependencies = [ [[package]] name = "fuels-macros" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bba1c2fd149a310879249144f2589336708ae860563a45b792907ae34ae6b959" +checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3695,9 +3696,9 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a45652fa07c48d5fba2ee50ddd279eead2c55b251b3d426d2189394b475330e9" +checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" dependencies = [ "async-trait", "fuel-abi-types", @@ -3714,14 +3715,15 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.65.1" +version = "0.66.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "967a140a51095d071c84970365c37f856f4f098b835cb609b934dff4b8296cce" +checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" dependencies = [ "fuel-core-chain-config", "fuel-core-client", "fuel-core-poa", "fuel-core-services", + "fuel-core-types", "fuel-crypto", "fuel-tx", "fuel-types", @@ -4162,6 +4164,9 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] [[package]] name = "histogram" @@ -4590,6 +4595,7 @@ dependencies = [ "async-trait", "fuels", "futures", + "hex 0.4.3", "hyperlane-core", "serde", "thiserror", @@ -7903,9 +7909,9 @@ dependencies = [ [[package]] name = "secp256k1" -version = "0.26.0" +version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4124a35fe33ae14259c490fd70fa199a32b9ce9502f2ee6bc4f81ec06fa65894" +checksum = "9465315bc9d4566e1724f0fffcbcc446268cb522e60f9a27bcded6b19c108113" dependencies = [ "rand 0.8.5", "secp256k1-sys", @@ -7913,9 +7919,9 @@ dependencies = [ [[package]] name = "secp256k1-sys" -version = "0.8.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70a129b9e9efbfb223753b9163c4ab3b13cff7fd9c7f010fbac25ab4099fa07e" +checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9" dependencies = [ "cc", ] diff --git a/rust/main/Cargo.toml b/rust/main/Cargo.toml index dab1d9cc4f..0f94ce91fe 100644 --- a/rust/main/Cargo.toml +++ b/rust/main/Cargo.toml @@ -61,8 +61,8 @@ dhat = "0.3.3" ed25519-dalek = "~1.0" eyre = "=0.6.8" fixed-hash = "0.8.0" -fuels = "0.65.0" -fuels-code-gen = "0.65.0" +fuels = "0.66.5" +fuels-code-gen = "0.66.5" futures = "0.3" futures-util = "0.3" generic-array = { version = "0.14", features = ["serde", "more_lengths"] } diff --git a/rust/main/chains/hyperlane-fuel/Cargo.toml b/rust/main/chains/hyperlane-fuel/Cargo.toml index bb82a9c077..3b8f795983 100644 --- a/rust/main/chains/hyperlane-fuel/Cargo.toml +++ b/rust/main/chains/hyperlane-fuel/Cargo.toml @@ -16,6 +16,7 @@ serde.workspace = true thiserror.workspace = true tracing-futures.workspace = true tracing.workspace = true +hex.workspace = true url.workspace = true hyperlane-core = { path = "../../hyperlane-core", features = ["async"] } diff --git a/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json new file mode 100644 index 0000000000..c0c2c90bd6 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json @@ -0,0 +1,559 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "metadataTypeId": 0 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum AggregationIsmError", + "concreteTypeId": "0ea8621ef67fa15d0d7ae795a3f434f12a683909e6c2096ed7ba493fa6dba43a", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 2 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 3 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 4 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 5 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 6 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 10 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 12 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 15 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 17 + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 14, + "typeArguments": [ + { + "name": "", + "typeId": 12 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "enum AggregationIsmError", + "metadataTypeId": 1, + "components": [ + { + "name": "DidNotMeetThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AlreadyInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NotInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 2, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ARB_L2_TO_L1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 3, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 4, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 5 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 5, + "components": [ + { + "name": "Address", + "typeId": 9 + }, + { + "name": "ContractId", + "typeId": 12 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 6, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 7 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 8 + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 9, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 10, + "components": [ + { + "name": "buf", + "typeId": 11 + }, + { + "name": "len", + "typeId": 18 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 11, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 12, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 13, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 14, + "components": [ + { + "name": "buf", + "typeId": 13, + "typeArguments": [ + { + "name": "", + "typeId": 7 + } + ] + }, + { + "name": "len", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 15, + "components": [ + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 16, + "components": [ + { + "name": "new_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 5 + }, + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 18 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "modules_and_threshold", + "output": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "module", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "enroll_module", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "set_threshold", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "1056201997742481757", + "concreteTypeId": "0ea8621ef67fa15d0d7ae795a3f434f12a683909e6c2096ed7ba493fa6dba43a" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] + } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json b/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json new file mode 100644 index 0000000000..4041902996 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json @@ -0,0 +1,709 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "enum IgpError", + "concreteTypeId": "5e9b943fe66bb2f9186016140592021f71cf98395bd3c80eef479a17a9b39e2b", + "metadataTypeId": 0 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 1 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 2 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 3 + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "metadataTypeId": 4, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "metadataTypeId": 4, + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 5 + }, + { + "type": "str", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "type": "struct interfaces::igp::BeneficiarySetEvent", + "concreteTypeId": "1c700488fc3eb12cecb5df0f1d7fab50a48794cd700cb26c6e93e9762fa84658", + "metadataTypeId": 7 + }, + { + "type": "struct interfaces::igp::ClaimEvent", + "concreteTypeId": "fc2d85b6d4433b18adbc77d4019fdd47213b2df923dcc52543a16d1a9462778a", + "metadataTypeId": 8 + }, + { + "type": "struct interfaces::igp::GasOracleSetEvent", + "concreteTypeId": "e2a62dd30c887a49893c650f8f85200415866051cadc94f195537b3798498065", + "metadataTypeId": 9 + }, + { + "type": "struct interfaces::igp::GasPaymentEvent", + "concreteTypeId": "57f16a22cb9e861b379fae117dc32f53512234a762ed50564496dff7600646b9", + "metadataTypeId": 10 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 13 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 14 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 15 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypes": [ + { + "type": "enum IgpError", + "metadataTypeId": 0, + "components": [ + { + "name": "InsufficientGasPayment", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InvalidGasOracle", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "QuoteGasPaymentOverflow", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InterchainGasPaymentInBaseAsset", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 1, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 2, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 3 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 3, + "components": [ + { + "name": "Address", + "typeId": 11 + }, + { + "name": "ContractId", + "typeId": 12 + } + ] + }, + { + "type": "enum std::option::Option", + "metadataTypeId": 4, + "components": [ + { + "name": "None", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Some", + "typeId": 6 + } + ], + "typeParameters": [ + 6 + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 5, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 6 + }, + { + "type": "struct interfaces::igp::BeneficiarySetEvent", + "metadataTypeId": 7, + "components": [ + { + "name": "beneficiary", + "typeId": 3 + } + ] + }, + { + "type": "struct interfaces::igp::ClaimEvent", + "metadataTypeId": 8, + "components": [ + { + "name": "beneficiary", + "typeId": 3 + }, + { + "name": "amount", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::igp::GasOracleSetEvent", + "metadataTypeId": 9, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct interfaces::igp::GasPaymentEvent", + "metadataTypeId": 10, + "components": [ + { + "name": "message_id", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "gas_amount", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "payment", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 11, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 12, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 13, + "components": [ + { + "name": "previous_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 14, + "components": [ + { + "name": "new_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 15, + "components": [ + { + "name": "new_owner", + "typeId": 3 + }, + { + "name": "previous_owner", + "typeId": 3 + } + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "gas_oracle", + "output": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message_id", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_amount", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "refund_address", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "pay_for_gas", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + }, + { + "name": "payable", + "arguments": [] + } + ] + }, + { + "inputs": [ + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_amount", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "quote_gas_payment", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Quotes the required interchain gas payment to be paid in the base asset." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `destination_domain` - The destination domain of the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `gas_amount` - The amount of destination gas to pay for." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set_gas_oracle", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "beneficiary", + "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the current beneficiary." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "claim", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "beneficiary", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "set_beneficiary", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_gas_oracle", + "output": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the gas oracle for a given domain." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set_gas_from_oracle", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the gas oracle for a given domain." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "gas_overhead", + "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_overhead", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "set_gas_overhead", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "6817205463125046009", + "concreteTypeId": "5e9b943fe66bb2f9186016140592021f71cf98395bd3c80eef479a17a9b39e2b" + }, + { + "logId": "10098701174489624218", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "logId": "6336962848364594715", + "concreteTypeId": "57f16a22cb9e861b379fae117dc32f53512234a762ed50564496dff7600646b9" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "16331791483177302601", + "concreteTypeId": "e2a62dd30c887a49893c650f8f85200415866051cadc94f195537b3798498065" + }, + { + "logId": "18171327091801537304", + "concreteTypeId": "fc2d85b6d4433b18adbc77d4019fdd47213b2df923dcc52543a16d1a9462778a" + }, + { + "logId": "2049142816847606060", + "concreteTypeId": "1c700488fc3eb12cecb5df0f1d7fab50a48794cd700cb26c6e93e9762fa84658" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] + } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json b/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json new file mode 100644 index 0000000000..2079ef84e3 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json @@ -0,0 +1,346 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum MessageIdMultisigError", + "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 3 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 6 + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 10 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 10 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum MessageIdMultisigError", + "metadataTypeId": 2, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 6 + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 3, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 4 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 5 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 6, + "components": [ + { + "name": "buf", + "typeId": 7 + }, + { + "name": "len", + "typeId": 11 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 7, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 8, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 9, + "components": [ + { + "name": "buf", + "typeId": 8, + "typeArguments": [ + { + "name": "", + "typeId": 4 + } + ] + }, + { + "name": "len", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 11 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "digest", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "index", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "signature_at", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": null + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "validators_and_threshold", + "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + } + ], + "name": "enroll_validator", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "set_threshold", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "12857203263801679462", + "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e" + } + ], + "messagesTypes": [], + "configurables": [] + } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json index 5c357aa4bc..ec2b5b7965 100644 --- a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json @@ -1,410 +1,424 @@ { - "encoding": "1", - "types": [ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ { - "typeId": 0, "type": "()", - "components": [], - "typeParameters": null + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "typeId": 1, "type": "b256", - "components": null, - "typeParameters": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { - "typeId": 2, "type": "bool", - "components": null, - "typeParameters": null + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "typeId": 3, - "type": "enum AccessError", - "components": [ - { - "name": "NotOwner", - "type": 0, - "typeArguments": null - } - ], - "typeParameters": null + "type": "enum MailboxError", + "concreteTypeId": "440e9980d3bd496a07b9348ba2cc9553c25410fe4a1c251d8303bc073ca3c472", + "metadataTypeId": 0 }, { - "typeId": 4, - "type": "enum Identity", - "components": [ - { - "name": "Address", - "type": 11, - "typeArguments": null - }, - { - "name": "ContractId", - "type": 13, - "typeArguments": null - } - ], - "typeParameters": null + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 1 }, { - "typeId": 5, - "type": "enum InitializationError", - "components": [ - { - "name": "CannotReinitialized", - "type": 0, - "typeArguments": null - } - ], - "typeParameters": null + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 2 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 3 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 4 + }, + { + "type": "enum sway_libs::pausable::errors::PauseError", + "concreteTypeId": "8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc", + "metadataTypeId": 5 + }, + { + "type": "enum sway_libs::reentrancy::errors::ReentrancyError", + "concreteTypeId": "4d216c57b3357523323f59401c7355785b41bdf832f6e1106272186b94797038", + "metadataTypeId": 6 + }, + { + "type": "struct interfaces::mailbox::events::DefaultHookSetEvent", + "concreteTypeId": "f42f98beefff531713e86f8b0b1257193b6bd522d880b8c125e0396db2c24ee3", + "metadataTypeId": 8 + }, + { + "type": "struct interfaces::mailbox::events::DefaultIsmSetEvent", + "concreteTypeId": "8742fde87d84001c6590ba9c1448233175037fc3ef90b383fb6176ec01fda2ff", + "metadataTypeId": 9 + }, + { + "type": "struct interfaces::mailbox::events::DispatchEvent", + "concreteTypeId": "df0611b3b38657e8253e2c64c87af0b7082c972e9fbf22a0d61eff177cd5c71d", + "metadataTypeId": 10 + }, + { + "type": "struct interfaces::mailbox::events::DispatchIdEvent", + "concreteTypeId": "f4d83fa1c2e15e97430f0f61138ea404e6853cafd90da2b4609e2fa95d9e43c9", + "metadataTypeId": 11 + }, + { + "type": "struct interfaces::mailbox::events::ProcessEvent", + "concreteTypeId": "019ee4dbd8a5c577232b95d738e0bbcb2898c0417c9e0b05694284994582a199", + "metadataTypeId": 12 + }, + { + "type": "struct interfaces::mailbox::events::RequiredHookSetEvent", + "concreteTypeId": "be7aa440073b70d771ca9ed0e1520ed742cf67643ad38de897637be76a2fe6ea", + "metadataTypeId": 13 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 16 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 18 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 19 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 20 }, { - "typeId": 6, + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 21 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypes": [ + { "type": "enum MailboxError", + "metadataTypeId": 0, "components": [ { "name": "InvalidISMAddress", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "InvalidHookAddress", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "InvalidProtocolVersion", - "type": 27, - "typeArguments": null + "typeId": 22 }, { "name": "InvalidMessageOrigin", - "type": 25, - "typeArguments": null + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" }, { "name": "MessageAlreadyDelivered", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "MessageVerificationFailed", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "AlreadyInitialized", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "MessageTooLarge", - "type": 26, - "typeArguments": null - } - ], - "typeParameters": null - }, - { - "typeId": 7, - "type": "enum PauseError", - "components": [ - { - "name": "Paused", - "type": 0, - "typeArguments": null - }, - { - "name": "NotPaused", - "type": 0, - "typeArguments": null + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } - ], - "typeParameters": null + ] }, { - "typeId": 8, - "type": "enum ReentrancyError", + "type": "enum standards::src5::AccessError", + "metadataTypeId": 1, "components": [ { - "name": "NonReentrant", - "type": 0, - "typeArguments": null + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } - ], - "typeParameters": null + ] }, { - "typeId": 9, - "type": "enum State", + "type": "enum standards::src5::State", + "metadataTypeId": 2, "components": [ { "name": "Uninitialized", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { "name": "Initialized", - "type": 4, - "typeArguments": null + "typeId": 3 }, { "name": "Revoked", - "type": 0, - "typeArguments": null + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } - ], - "typeParameters": null + ] }, { - "typeId": 10, - "type": "raw untyped ptr", - "components": null, - "typeParameters": null + "type": "enum std::identity::Identity", + "metadataTypeId": 3, + "components": [ + { + "name": "Address", + "typeId": 15 + }, + { + "name": "ContractId", + "typeId": 18 + } + ] }, { - "typeId": 11, - "type": "struct Address", + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 4, "components": [ { - "name": "bits", - "type": 1, - "typeArguments": null + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } - ], - "typeParameters": null + ] }, { - "typeId": 12, - "type": "struct Bytes", + "type": "enum sway_libs::pausable::errors::PauseError", + "metadataTypeId": 5, "components": [ { - "name": "buf", - "type": 23, - "typeArguments": null + "name": "Paused", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "len", - "type": 26, - "typeArguments": null + "name": "NotPaused", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } - ], - "typeParameters": null + ] }, { - "typeId": 13, - "type": "struct ContractId", + "type": "enum sway_libs::reentrancy::errors::ReentrancyError", + "metadataTypeId": 6, "components": [ { - "name": "bits", - "type": 1, - "typeArguments": null + "name": "NonReentrant", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } - ], - "typeParameters": null + ] + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 7 }, { - "typeId": 14, - "type": "struct DefaultHookSetEvent", + "type": "struct interfaces::mailbox::events::DefaultHookSetEvent", + "metadataTypeId": 8, "components": [ { "name": "module", - "type": 13, - "typeArguments": null + "typeId": 18 } - ], - "typeParameters": null + ] }, { - "typeId": 15, - "type": "struct DefaultIsmSetEvent", + "type": "struct interfaces::mailbox::events::DefaultIsmSetEvent", + "metadataTypeId": 9, "components": [ { "name": "module", - "type": 13, - "typeArguments": null + "typeId": 18 } - ], - "typeParameters": null + ] }, { - "typeId": 16, - "type": "struct DispatchEvent", + "type": "struct interfaces::mailbox::events::DispatchEvent", + "metadataTypeId": 10, "components": [ { "name": "message_id", - "type": 1, - "typeArguments": null + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "destination_domain", - "type": 25, - "typeArguments": null + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" }, { "name": "recipient_address", - "type": 1, - "typeArguments": null + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "message", - "type": 18, - "typeArguments": null + "typeId": 14 } - ], - "typeParameters": null + ] }, { - "typeId": 17, - "type": "struct DispatchIdEvent", + "type": "struct interfaces::mailbox::events::DispatchIdEvent", + "metadataTypeId": 11, "components": [ { "name": "message_id", - "type": 1, - "typeArguments": null + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } - ], - "typeParameters": null + ] }, { - "typeId": 18, - "type": "struct EncodedMessage", + "type": "struct interfaces::mailbox::events::ProcessEvent", + "metadataTypeId": 12, "components": [ { - "name": "bytes", - "type": 12, - "typeArguments": null + "name": "message_id", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "origin", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "sender", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "recipient", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } - ], - "typeParameters": null + ] }, { - "typeId": 19, - "type": "struct OwnershipRenounced", + "type": "struct interfaces::mailbox::events::RequiredHookSetEvent", + "metadataTypeId": 13, "components": [ { - "name": "previous_owner", - "type": 4, - "typeArguments": null + "name": "module", + "typeId": 18 } - ], - "typeParameters": null + ] }, { - "typeId": 20, - "type": "struct OwnershipSet", + "type": "struct message::EncodedMessage", + "metadataTypeId": 14, "components": [ { - "name": "new_owner", - "type": 4, - "typeArguments": null + "name": "bytes", + "typeId": 16 } - ], - "typeParameters": null + ] }, { - "typeId": 21, - "type": "struct OwnershipTransferred", + "type": "struct std::address::Address", + "metadataTypeId": 15, "components": [ { - "name": "new_owner", - "type": 4, - "typeArguments": null - }, - { - "name": "previous_owner", - "type": 4, - "typeArguments": null + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } - ], - "typeParameters": null + ] }, { - "typeId": 22, - "type": "struct ProcessEvent", + "type": "struct std::bytes::Bytes", + "metadataTypeId": 16, "components": [ { - "name": "message_id", - "type": 1, - "typeArguments": null - }, - { - "name": "origin", - "type": 25, - "typeArguments": null - }, - { - "name": "sender", - "type": 1, - "typeArguments": null + "name": "buf", + "typeId": 17 }, { - "name": "recipient", - "type": 1, - "typeArguments": null + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } - ], - "typeParameters": null + ] }, { - "typeId": 23, - "type": "struct RawBytes", + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 17, "components": [ { "name": "ptr", - "type": 10, - "typeArguments": null + "typeId": 7 }, { "name": "cap", - "type": 26, - "typeArguments": null + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } - ], - "typeParameters": null + ] }, { - "typeId": 24, - "type": "struct RequiredHookSetEvent", + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 18, "components": [ { - "name": "module", - "type": 13, - "typeArguments": null + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } - ], - "typeParameters": null + ] }, { - "typeId": 25, - "type": "u32", - "components": null, - "typeParameters": null + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 19, + "components": [ + { + "name": "previous_owner", + "typeId": 3 + } + ] }, { - "typeId": 26, - "type": "u64", - "components": null, - "typeParameters": null + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 20, + "components": [ + { + "name": "new_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 21, + "components": [ + { + "name": "new_owner", + "typeId": 3 + }, + { + "name": "previous_owner", + "typeId": 3 + } + ] }, { - "typeId": 27, "type": "u8", - "components": null, - "typeParameters": null + "metadataTypeId": 22 } ], "functions": [ { "inputs": [], "name": "default_hook", - "output": { - "name": "", - "type": 13, - "typeArguments": null - }, + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", "attributes": [ { "name": "doc-comment", @@ -423,11 +437,7 @@ { "inputs": [], "name": "default_ism", - "output": { - "name": "", - "type": 13, - "typeArguments": null - }, + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", "attributes": [ { "name": "doc-comment", @@ -447,16 +457,11 @@ "inputs": [ { "name": "message_id", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ], "name": "delivered", - "output": { - "name": "", - "type": 2, - "typeArguments": null - }, + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "attributes": [ { "name": "doc-comment", @@ -500,36 +505,27 @@ "inputs": [ { "name": "destination_domain", - "type": 25, - "typeArguments": null + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" }, { "name": "recipient_address", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "message_body", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { "name": "metadata", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { "name": "hook", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "dispatch", - "output": { - "name": "", - "type": 1, - "typeArguments": null - }, + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ { "name": "doc-comment", @@ -596,31 +592,23 @@ "inputs": [ { "name": "owner", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "default_ism", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "default_hook", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "required_hook", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ], "name": "initialize", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", @@ -639,11 +627,7 @@ { "inputs": [], "name": "latest_dispatched_id", - "output": { - "name": "", - "type": 1, - "typeArguments": null - }, + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ { "name": "storage", @@ -656,11 +640,7 @@ { "inputs": [], "name": "local_domain", - "output": { - "name": "", - "type": 25, - "typeArguments": null - }, + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "attributes": [ { "name": "doc-comment", @@ -679,11 +659,7 @@ { "inputs": [], "name": "nonce", - "output": { - "name": "", - "type": 25, - "typeArguments": null - }, + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "attributes": [ { "name": "storage", @@ -697,21 +673,15 @@ "inputs": [ { "name": "metadata", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { "name": "message", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" } ], "name": "process", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", @@ -762,36 +732,27 @@ "inputs": [ { "name": "destination_domain", - "type": 25, - "typeArguments": null + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" }, { "name": "recipient_address", - "type": 1, - "typeArguments": null + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { "name": "message_body", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { "name": "metadata", - "type": 12, - "typeArguments": null + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { "name": "hook", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "quote_dispatch", - "output": { - "name": "", - "type": 26, - "typeArguments": null - }, + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", "attributes": [ { "name": "doc-comment", @@ -847,16 +808,11 @@ "inputs": [ { "name": "recipient", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "recipient_ism", - "output": { - "name": "", - "type": 13, - "typeArguments": null - }, + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", "attributes": [ { "name": "storage", @@ -870,11 +826,7 @@ { "inputs": [], "name": "required_hook", - "output": { - "name": "", - "type": 13, - "typeArguments": null - }, + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", "attributes": [ { "name": "doc-comment", @@ -894,16 +846,11 @@ "inputs": [ { "name": "module", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "set_default_hook", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", @@ -923,16 +870,11 @@ "inputs": [ { "name": "module", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "set_default_ism", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", @@ -977,16 +919,11 @@ "inputs": [ { "name": "module", - "type": 13, - "typeArguments": null + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "set_required_hook", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", @@ -1005,11 +942,7 @@ { "inputs": [], "name": "is_paused", - "output": { - "name": "", - "type": 2, - "typeArguments": null - }, + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "attributes": [ { "name": "storage", @@ -1022,11 +955,7 @@ { "inputs": [], "name": "pause", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1039,11 +968,7 @@ { "inputs": [], "name": "unpause", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1057,16 +982,11 @@ "inputs": [ { "name": "new_owner", - "type": 4, - "typeArguments": null + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" } ], "name": "initialize_ownership", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1080,11 +1000,7 @@ { "inputs": [], "name": "only_owner", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1097,11 +1013,7 @@ { "inputs": [], "name": "owner", - "output": { - "name": "", - "type": 9, - "typeArguments": null - }, + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", "attributes": [ { "name": "storage", @@ -1114,11 +1026,7 @@ { "inputs": [], "name": "renounce_ownership", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1133,16 +1041,11 @@ "inputs": [ { "name": "new_owner", - "type": 4, - "typeArguments": null + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" } ], "name": "transfer_ownership", - "output": { - "name": "", - "type": 0, - "typeArguments": null - }, + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "storage", @@ -1156,127 +1059,67 @@ "loggedTypes": [ { "logId": "5557842539076482339", - "loggedType": { - "name": "", - "type": 8, - "typeArguments": [] - } + "concreteTypeId": "4d216c57b3357523323f59401c7355785b41bdf832f6e1106272186b94797038" }, { "logId": "10032608944051208538", - "loggedType": { - "name": "", - "type": 7, - "typeArguments": [] - } + "concreteTypeId": "8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc" }, { "logId": "4904025822840310122", - "loggedType": { - "name": "", - "type": 6, - "typeArguments": [] - } + "concreteTypeId": "440e9980d3bd496a07b9348ba2cc9553c25410fe4a1c251d8303bc073ca3c472" }, { - "logId": "10811788483172643035", - "loggedType": { - "name": "", - "type": 16, - "typeArguments": [] - } + "logId": "16070551783826937832", + "concreteTypeId": "df0611b3b38657e8253e2c64c87af0b7082c972e9fbf22a0d61eff177cd5c71d" }, { - "logId": "2522729423758891677", - "loggedType": { - "name": "", - "type": 17, - "typeArguments": [] - } + "logId": "17642921504215752343", + "concreteTypeId": "f4d83fa1c2e15e97430f0f61138ea404e6853cafd90da2b4609e2fa95d9e43c9" }, { "logId": "2161305517876418151", - "loggedType": { - "name": "", - "type": 5, - "typeArguments": [] - } + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" }, { "logId": "16280289466020123285", - "loggedType": { - "name": "", - "type": 20, - "typeArguments": [] - } + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" }, { - "logId": "7929134096091764817", - "loggedType": { - "name": "", - "type": 22, - "typeArguments": [] - } + "logId": "116782273241924983", + "concreteTypeId": "019ee4dbd8a5c577232b95d738e0bbcb2898c0417c9e0b05694284994582a199" }, { "logId": "4571204900286667806", - "loggedType": { - "name": "", - "type": 3, - "typeArguments": [] - } + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" }, { - "logId": "14400248731700551312", - "loggedType": { - "name": "", - "type": 14, - "typeArguments": [] - } + "logId": "17595450214997512983", + "concreteTypeId": "f42f98beefff531713e86f8b0b1257193b6bd522d880b8c125e0396db2c24ee3" }, { - "logId": "1889958695533330661", - "loggedType": { - "name": "", - "type": 15, - "typeArguments": [] - } + "logId": "9746631718563217436", + "concreteTypeId": "8742fde87d84001c6590ba9c1448233175037fc3ef90b383fb6176ec01fda2ff" }, { - "logId": "1134555198745859881", - "loggedType": { - "name": "", - "type": 24, - "typeArguments": [] - } + "logId": "13725463409271206103", + "concreteTypeId": "be7aa440073b70d771ca9ed0e1520ed742cf67643ad38de897637be76a2fe6ea" }, { "logId": "4883303303013154842", - "loggedType": { - "name": "", - "type": 19, - "typeArguments": [] - } + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" }, { "logId": "12970362301975156672", - "loggedType": { - "name": "", - "type": 21, - "typeArguments": [] - } + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" } ], "messagesTypes": [], "configurables": [ { "name": "LOCAL_DOMAIN", - "configurableType": { - "name": "", - "type": 25, - "typeArguments": null - }, - "offset": 51792 + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "offset": 56248 } ] } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json new file mode 100644 index 0000000000..57d7f34917 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json @@ -0,0 +1,409 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(b256, u32)", + "concreteTypeId": "ca65b5ac32a1d2b9c2c913a704974f17a67f9ed81cdd78007c6584eb8feb5e95", + "metadataTypeId": 0 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", + "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::merkle_tree_hook::MerkleTreeEvent", + "concreteTypeId": "13d1ea5564f062bef216aab38d2d55b58fb43f440a67b87a5f44af5c09faabcd", + "metadataTypeId": 3 + }, + { + "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", + "concreteTypeId": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", + "metadataTypeId": 4 + }, + { + "type": "enum merkle::MerkleError", + "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb", + "metadataTypeId": 5 + }, + { + "type": "struct merkle::MerkleTree", + "concreteTypeId": "4f367a560e7594cc203b566f49d1b5f9a43fb5e5c4172cef5eb32b9dc5a0d0df", + "metadataTypeId": 7 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 8 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 10 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "[_; 32]", + "metadataTypeId": 1, + "components": [ + { + "name": "__array_element", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", + "metadataTypeId": 2, + "components": [ + { + "name": "MessageNotDispatching", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "NoValueExpected", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ContractNotInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ContractAlreadyInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::merkle_tree_hook::MerkleTreeEvent", + "metadataTypeId": 3, + "components": [ + { + "name": "InsertedIntoTree", + "typeId": 0 + } + ] + }, + { + "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", + "metadataTypeId": 4, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_TREE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "INTERCHAIN_GAS_PAYMASTER", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FALLBACK_ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ID_AUTH_ISM", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PAUSABLE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PROTOCOL_FEE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LAYER_ZERO_V1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "RATE_LIMITED_HOOK", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum merkle::MerkleError", + "metadataTypeId": 5, + "components": [ + { + "name": "MerkleTreeFull", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct merkle::MerkleTree", + "metadataTypeId": 7, + "components": [ + { + "name": "branch", + "typeId": 1 + }, + { + "name": "count", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 8, + "components": [ + { + "name": "buf", + "typeId": 9 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 9, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + } + ], + "functions": [ + { + "inputs": [], + "name": "count", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "mailbox", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "latest_checkpoint", + "output": "ca65b5ac32a1d2b9c2c913a704974f17a67f9ed81cdd78007c6584eb8feb5e95", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "root", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "tree", + "output": "4f367a560e7594cc203b566f49d1b5f9a43fb5e5c4172cef5eb32b9dc5a0d0df", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "hook_type", + "output": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "_metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "post_dispatch", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "payable", + "arguments": [] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "_metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "_message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "quote_dispatch", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "_metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "supports_metadata", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "6057534559405907588", + "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5" + }, + { + "logId": "15984911484641280648", + "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb" + }, + { + "logId": "1428180209339753150", + "concreteTypeId": "13d1ea5564f062bef216aab38d2d55b58fb43f440a67b87a5f44af5c09faabcd" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json new file mode 100644 index 0000000000..2079ef84e3 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json @@ -0,0 +1,346 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum MessageIdMultisigError", + "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 3 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 6 + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 10 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 10 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum MessageIdMultisigError", + "metadataTypeId": 2, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 6 + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 3, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 4 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 5 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 6, + "components": [ + { + "name": "buf", + "typeId": 7 + }, + { + "name": "len", + "typeId": 11 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 7, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 8, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 9, + "components": [ + { + "name": "buf", + "typeId": 8, + "typeArguments": [ + { + "name": "", + "typeId": 4 + } + ] + }, + { + "name": "len", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 11 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "digest", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "index", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "signature_at", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": null + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "validators_and_threshold", + "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + } + ], + "name": "enroll_validator", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "set_threshold", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "12857203263801679462", + "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e" + } + ], + "messagesTypes": [], + "configurables": [] + } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json new file mode 100644 index 0000000000..26aea85f59 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json @@ -0,0 +1,627 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum DomainRoutingIsmError", + "concreteTypeId": "d6a68e63771bcc70200ac9382eacbf6434843d6e1d95b91d3d4752aaa277bb50", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 2 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 3 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 4 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 5 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 6 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 10 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "metadataTypeId": 14, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "metadataTypeId": 14, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 15 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 17 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 18 + }, + { + "name": "__tuple_element", + "typeId": 18 + } + ] + }, + { + "type": "enum DomainRoutingIsmError", + "metadataTypeId": 1, + "components": [ + { + "name": "AlreadyInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NotInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "DomainModuleLengthMismatch", + "typeId": 0 + }, + { + "name": "DomainNotSet", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 2, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ARB_L2_TO_L1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 3, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 4, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 5 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 5, + "components": [ + { + "name": "Address", + "typeId": 9 + }, + { + "name": "ContractId", + "typeId": 12 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 6, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 7 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 8 + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 9, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 10, + "components": [ + { + "name": "buf", + "typeId": 11 + }, + { + "name": "len", + "typeId": 18 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 11, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 12, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 13, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 14, + "components": [ + { + "name": "buf", + "typeId": 13, + "typeArguments": [ + { + "name": "", + "typeId": 7 + } + ] + }, + { + "name": "len", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 15, + "components": [ + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 16, + "components": [ + { + "name": "new_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 5 + }, + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 18 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": null + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "route", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "domains", + "output": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "domains", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a" + }, + { + "name": "modules", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198" + } + ], + "name": "initialize_with_domains", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "module", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "remove", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "module", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "15467206528101764208", + "concreteTypeId": "d6a68e63771bcc70200ac9382eacbf6434843d6e1d95b91d3d4752aaa277bb50" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json b/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json new file mode 100644 index 0000000000..8215973296 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json @@ -0,0 +1,483 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "[u8; 32]", + "concreteTypeId": "c0cb0154daecd457849d890b38a00e4ebac52e820cb461e0477aaadee6919e1e", + "metadataTypeId": 1 + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum ValidatorAnnounceError", + "concreteTypeId": "6dea538ce06cc546aa65f360420bf2395788f6009094d96bedda53dc9e364178", + "metadataTypeId": 2 + }, + { + "type": "struct interfaces::va::ValidatorAnnouncementEvent", + "concreteTypeId": "d99160a54786c91aa3bfabca957c17df96dbae05a4c79f958b3da89ddc751fbf", + "metadataTypeId": 5 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 6 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 8 + }, + { + "type": "struct std::string::String", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c", + "metadataTypeId": 9 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "metadataTypeId": 11, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8", + "metadataTypeId": 11, + "typeArguments": [ + "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + ] + }, + { + "type": "struct std::vec::Vec>", + "concreteTypeId": "356056ebd0caea5064f10ead20d08a92ad675e09e3fa875f9d632a675fdea875", + "metadataTypeId": 11, + "typeArguments": [ + "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8" + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 12 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "[_; 32]", + "metadataTypeId": 1, + "components": [ + { + "name": "__array_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "enum ValidatorAnnounceError", + "metadataTypeId": 2, + "components": [ + { + "name": "ValidatorNotSigner", + "typeId": 0 + }, + { + "name": "ReplayAnnouncement", + "typeId": 0 + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 3 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 4 + }, + { + "type": "struct interfaces::va::ValidatorAnnouncementEvent", + "metadataTypeId": 5, + "components": [ + { + "name": "validator", + "typeId": 12 + }, + { + "name": "storage_location", + "typeId": 9 + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 6, + "components": [ + { + "name": "buf", + "typeId": 7 + }, + { + "name": "len", + "typeId": 13 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 7, + "components": [ + { + "name": "ptr", + "typeId": 4 + }, + { + "name": "cap", + "typeId": 13 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 8, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::string::String", + "metadataTypeId": 9, + "components": [ + { + "name": "bytes", + "typeId": 6 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 10, + "components": [ + { + "name": "ptr", + "typeId": 4 + }, + { + "name": "cap", + "typeId": 13 + } + ], + "typeParameters": [ + 3 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 11, + "components": [ + { + "name": "buf", + "typeId": 10, + "typeArguments": [ + { + "name": "", + "typeId": 3 + } + ] + }, + { + "name": "len", + "typeId": 13 + } + ], + "typeParameters": [ + 3 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 12, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "u64", + "metadataTypeId": 13 + } + ], + "functions": [ + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + }, + { + "name": "storage_location", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + }, + { + "name": "signature", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "announce", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Announces a validator signature storage location " + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validator`: [b256] - The address of the validator" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `storage_location`: [string] - Information encoding the location of signed checkpoints" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `signature`: [bytes] - The signed validator announcement" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - Whether the announcement was successful" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the announcement has already been made" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the validator is not the signer of the announcement" + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validators", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198" + } + ], + "name": "get_announced_storage_locations", + "output": "356056ebd0caea5064f10ead20d08a92ad675e09e3fa875f9d632a675fdea875", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns a list of all announced storage locations " + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validators`: [Vec] - The list of validators to get storage locations for" + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "get_announced_validators", + "output": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns a list of validators that have made announcements" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of validators that have made announcements" + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "7920234759210190150", + "concreteTypeId": "6dea538ce06cc546aa65f360420bf2395788f6009094d96bedda53dc9e364178" + }, + { + "logId": "13892198939516261463", + "concreteTypeId": "c0cb0154daecd457849d890b38a00e4ebac52e820cb461e0477aaadee6919e1e" + }, + { + "logId": "14454674236531057292", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + }, + { + "logId": "15677418040839293210", + "concreteTypeId": "d99160a54786c91aa3bfabca957c17df96dbae05a4c79f958b3da89ddc751fbf" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "LOCAL_DOMAIN", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "offset": 39256 + }, + { + "name": "MAILBOX_ID", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "offset": 39264 + } + ] +} \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs new file mode 100644 index 0000000000..33b4ef0c2e --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs @@ -0,0 +1,77 @@ +use crate::{ + contracts::aggregation_ism::AggregationISM as AggregationIsmContract, conversions::*, + ConnectionConf, FuelProvider, +}; +use async_trait::async_trait; +use fuels::{ + accounts::wallet::WalletUnlocked, + types::{bech32::Bech32ContractId, Bytes}, +}; +use hyperlane_core::{ + AggregationIsm, ChainCommunicationError, ChainResult, ContractLocator, Encode, HyperlaneChain, + HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, H256, +}; + +/// A reference to a AggregationIsm contract on some Fuel chain +#[derive(Debug)] +pub struct FuelAggregationIsm { + contract: AggregationIsmContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelAggregationIsm { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelAggregationIsm { + contract: AggregationIsmContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} + +impl HyperlaneContract for FuelAggregationIsm { + fn address(&self) -> H256 { + self.contract.contract_id().into_h256() + } +} + +impl HyperlaneChain for FuelAggregationIsm { + fn domain(&self) -> &HyperlaneDomain { + &self.domain + } + + fn provider(&self) -> Box { + Box::new(self.provider.clone()) + } +} + +#[async_trait] +impl AggregationIsm for FuelAggregationIsm { + async fn modules_and_threshold( + &self, + message: &HyperlaneMessage, + ) -> ChainResult<(Vec, u8)> { + self.contract + .methods() + .modules_and_threshold(Bytes(message.to_vec())) + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| { + let (modules, threshold) = res.value; + let modules = modules.iter().map(|v| v.into_h256()).collect(); + (modules, threshold) + }) + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/conversions.rs b/rust/main/chains/hyperlane-fuel/src/conversions.rs index af16b8067b..134fe7f17e 100644 --- a/rust/main/chains/hyperlane-fuel/src/conversions.rs +++ b/rust/main/chains/hyperlane-fuel/src/conversions.rs @@ -1,4 +1,72 @@ -use hyperlane_core::H256; +use hyperlane_core::{ModuleType, H160, H256}; + +use fuels::types::{Bits256, EvmAddress}; + +/// Wrapper around the Fuel ModuleType enum. +pub struct IsmType(pub crate::contracts::interchain_security_module::ModuleType); + +/// Trait for converting an array of Bits256 to an array of H256. +pub trait FromBits256Array { + /// Convert into an array of H256 + fn into_h256_array(self) -> [H256; 32]; +} + +impl FromBits256Array for [Bits256; 32] { + fn into_h256_array(self) -> [H256; 32] { + let mut h256_array: [H256; 32] = [H256::zero(); 32]; + for (i, bits256) in self.iter().enumerate() { + h256_array[i] = H256::from(bits256.0); + } + h256_array + } +} + +/// Trait for convertring a vector of Fuel EvmAddresses to H256 +pub trait FromEvmAddressVec { + /// Convert the vector contents into H256 + fn into_h256_vec(self) -> Vec; +} + +impl FromEvmAddressVec for Vec { + fn into_h256_vec(self) -> Vec { + self.into_iter() + .map(|evm_address| evm_address.into_h256()) + .collect() + } +} + +impl From for ModuleType { + fn from(value: IsmType) -> Self { + match value.0 { + crate::contracts::interchain_security_module::ModuleType::UNUSED => ModuleType::Unused, + crate::contracts::interchain_security_module::ModuleType::ROUTING => { + ModuleType::Routing + } + crate::contracts::interchain_security_module::ModuleType::AGGREGATION => { + ModuleType::Aggregation + } + crate::contracts::interchain_security_module::ModuleType::LEGACY_MULTISIG => { + ModuleType::MessageIdMultisig + } + crate::contracts::interchain_security_module::ModuleType::MERKLE_ROOT_MULTISIG => { + ModuleType::MerkleRootMultisig + } + crate::contracts::interchain_security_module::ModuleType::MESSAGE_ID_MULTISIG => { + ModuleType::MessageIdMultisig + } + crate::contracts::interchain_security_module::ModuleType::NULL => ModuleType::Null, + crate::contracts::interchain_security_module::ModuleType::CCIP_READ => { + ModuleType::CcipRead + } + } + } +} + +/// Conversion from a primitive to fuel EvmAddress. +pub trait FuelIntoEvmAddress { + /// Convert to an EvmAddress. + fn into_evm_address(self) -> EvmAddress; +} /// Conversion from a fuel type to H256 primitive. pub trait FuelIntoH256 { @@ -44,7 +112,7 @@ impl_h256!( ); impl_h256!(fuels::types::Bits256, |v| fuels::types::Bits256(v.0), |v| { - H256::from(v.0) + H256(v.0) }); impl_h256!( @@ -58,3 +126,34 @@ impl_h256!( |v| fuels::types::Bytes32::new(v.0), |v| H256::from(*v) ); + +impl_h256!( + fuels::types::EvmAddress, + |v| fuels::types::EvmAddress::from(Bits256(v.0)), + |v| H256(v.value().0) +); + +macro_rules! impl_evm_address { + ($type:ty, $method:expr) => { + impl FuelIntoEvmAddress for $type { + fn into_evm_address(self) -> EvmAddress { + let method: fn($type) -> EvmAddress = $method; + method(self) + } + } + + impl FuelIntoEvmAddress for &$type { + fn into_evm_address(self) -> EvmAddress { + let method: fn($type) -> EvmAddress = $method; + method(self.clone()) + } + } + }; +} + +impl_evm_address!(H160, |v: H160| { + let mut padded = [0u8; 32]; + padded[12..32].copy_from_slice(&v.0); + EvmAddress::from(Bits256(padded)) +}); +impl_evm_address!(Bits256, |v: Bits256| EvmAddress::from(v)); diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs new file mode 100644 index 0000000000..5cb8323028 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -0,0 +1,333 @@ +use crate::{conversions::*, ConnectionConf, FuelProvider}; +use fuels::{ + accounts::wallet::WalletUnlocked, + client::{PageDirection, PaginationRequest}, + tx::Receipt, + types::{ + bech32::Bech32ContractId, + transaction::{Transaction, TransactionType}, + transaction_response::TransactionResponse, + tx_status::TxStatus, + BlockHeight, Bytes32, ContractId, + }, +}; +use futures::lock::Mutex; +use hyperlane_core::{ + ChainCommunicationError, ChainResult, ContractLocator, Indexed, LogMeta, H512, U256, +}; +use std::{ + collections::HashMap, + fmt::Debug, + ops::Deref, + sync::atomic::{AtomicBool, Ordering}, +}; + +// TODO, clippy issues + +/// A wrapper around a fuel provider to get generic blockchain information. +#[derive(Debug)] +pub struct FuelIndexer { + fuel_provider: FuelProvider, + contract_address: Bech32ContractId, + target_event_type: TransactionEventType, + block_cursor: Mutex>, + transaction_cursor: Mutex>, + cursors_initialized: AtomicBool, +} + +/// IGP payment log has a data length of 48 bytes +const IGP_PAYMENT_LOG_LENGTH: usize = 48; +/// Dispatch is the only function call on the mailbox that has 2 log data receipts +const DISPATCH_LOG_DATA_REC_AMOUNT: usize = 2; + +/// Types of transaction logs that can be indexed +#[derive(Debug, Clone)] +pub enum TransactionEventType { + /// Event when a Mailbox dispatches a message + MailboxDispatch, + /// Event when and IGP payment is processed + IgpPayment, + /// Event when a MerkleTreeHook insertion is processed + MerkleTreeHookInsert, +} + +impl FuelIndexer { + /// Create a new fuel indexer + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + wallet: WalletUnlocked, + target_event_type: TransactionEventType, + ) -> Self { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + let contract_address = Bech32ContractId::from_h256(&locator.address); + + Self { + fuel_provider, + contract_address, + target_event_type, + block_cursor: Mutex::new(None), + transaction_cursor: Mutex::new(None), + cursors_initialized: AtomicBool::default(), + } + } + + /// Index logs depending on which transaction parser is passed as a parameter + pub async fn index_logs_in_range( + &self, + range: std::ops::RangeInclusive, + parser: fn( + Vec<(Bytes32, TransactionResponse)>, + ) -> Vec<(Bytes32, TransactionResponse, T, U256)>, + ) -> ChainResult, LogMeta)>> + where + T: Into>, + T: PartialEq + Send + Sync + Debug + 'static, + { + if !self.cursors_initialized.load(Ordering::Relaxed) { + self.initialize_cursors(&range).await; + } + + let (transaction_amount, transaction_map) = self.get_block_data(range).await.unwrap(); + let transaction_data = self.get_transaction_data(&transaction_map).await; + + let full_tx_data = parser(transaction_data); + + let indexed_logs: Vec<(Indexed, LogMeta)> = full_tx_data + .into_iter() + .map(|(tx_id, tx, data, log_index)| { + let (block_hash, transaction_index) = transaction_map.get(&tx_id).unwrap(); + + let log_meta = LogMeta { + address: self.contract_address.clone().into_h256(), + block_number: *tx.block_height.unwrap().deref() as u64, + block_hash: block_hash.into_h256(), + transaction_id: H512::from(tx_id.into_h256()), + transaction_index: transaction_index.to_owned(), + log_index, + }; + + (data.into(), log_meta) + }) + .collect::>(); + + Ok(indexed_logs) + } + + /// Get the custom Fuel Provider + pub fn provider(&self) -> &FuelProvider { + &self.fuel_provider + } + + /// Check if a transaction is from a contract + /// @note: Only works for checking script transactions + /// Assumes that the first input is the contract id + #[allow(clippy::get_first)] + fn is_transaction_from_contract( + res: &TransactionResponse, + contract: &Bech32ContractId, + ) -> bool { + if let TransactionType::Script(script_transaction) = &res.transaction { + if script_transaction.inputs().get(0).is_some_and(|input| { + input + .contract_id() + .is_some_and(|id| id == &ContractId::from(&contract.into())) + }) { + return true; + } + } + false + } + + async fn get_transaction_data( + &self, + transaction_map: &HashMap, + ) -> Vec<(Bytes32, TransactionResponse)> { + let transaction_ids = transaction_map.keys().cloned().collect::>(); + let req = PaginationRequest { + cursor: self.transaction_cursor.lock().await.clone(), + results: transaction_ids.len() as i32, + direction: PageDirection::Forward, + }; + + let transactions = self + .fuel_provider + .provider() + .get_transactions(req) + .await + .map_err(ChainCommunicationError::from_other) + .unwrap(); + + *self.transaction_cursor.lock().await = transactions.cursor.clone(); + + assert!( + transactions.results.len() == transaction_ids.len(), + "Transaction data amount does not match transaction id amount" + ); + + let mut transaction_data = Vec::new(); + for (tx_id, tx_data) in transactions.results.iter().zip(transaction_ids) { + transaction_data.push((tx_data.clone(), tx_id.clone())); + } + + let transaction_matcher = self.get_transaction_matcher(); + + transaction_data + .into_iter() + .filter(|(_, tx_data)| { + Self::is_transaction_from_contract(&tx_data, &self.contract_address) + && transaction_matcher(&tx_data) + }) + .collect::>() + } + + async fn get_block_data( + &self, + range: std::ops::RangeInclusive, + ) -> ChainResult<(i32, HashMap)> { + let result_amount = range.end() - range.start() + 1; + let req = PaginationRequest { + cursor: self.block_cursor.lock().await.clone(), + results: i32::try_from(result_amount).expect("Invalid range"), + direction: PageDirection::Forward, + }; + + let blocks = self + .fuel_provider + .provider() + .get_blocks(req) + .await + .map_err(ChainCommunicationError::from_other)?; + *self.block_cursor.lock().await = blocks.cursor.clone(); + + let mut transaction_map: HashMap = HashMap::new(); + blocks.results.iter().for_each(|block| { + block + .transactions + .iter() + .enumerate() + .for_each(|(index, tx)| { + transaction_map.insert(tx.clone(), (block.id, index as u64)); + }); + }); + + let transaction_amount = blocks + .results + .iter() + .fold(0, |acc: usize, block| acc + block.transactions.len()) + as i32; + + Ok((transaction_amount, transaction_map)) + } + + async fn initialize_cursors(&self, range: &std::ops::RangeInclusive) { + let mut block_cursor_guard = self.block_cursor.lock().await; + let mut transaction_cursor_guard = self.transaction_cursor.lock().await; + assert!( + block_cursor_guard.is_none() && transaction_cursor_guard.is_none(), + "Cursors already initialized" + ); + + let range_start = range.start(); + if range.start() == &0 { + self.cursors_initialized.store(true, Ordering::Relaxed); + return; + } + + let start_block = BlockHeight::from(*range_start); + let block_data = self + .fuel_provider + .provider() + .block_by_height(start_block) + .await + .expect("Failed to get block data") + .unwrap(); + let first_transaction = block_data.transactions.first().unwrap(); + + let hex_block = hex::encode(range_start.to_be_bytes()); + let hex_tx = hex::encode(first_transaction.to_vec()); + let tx_cursor = Some(format!("{}#0x{}", hex_block, hex_tx)); + let block_cursor = Some(range_start.to_string()); + + *block_cursor_guard = block_cursor; + *transaction_cursor_guard = tx_cursor; + self.cursors_initialized.store(true, Ordering::Relaxed); + } +} + +// Functions to make sure that the correct function is being filtered +impl FuelIndexer { + /// Get the correct function to validate a transaction depending on the indexer event target + fn get_transaction_matcher(&self) -> for<'a> fn(&'a TransactionResponse) -> bool { + match self.target_event_type { + TransactionEventType::MailboxDispatch => Self::is_dispatch_call, + TransactionEventType::IgpPayment => Self::is_igp_payment, + TransactionEventType::MerkleTreeHookInsert => Self::is_merkle_tree_insertion, + } + } + + /// Check if a transaction is a call to the dispatch function of the Mailbox contract + fn is_dispatch_call(res: &TransactionResponse) -> bool { + let receipts = match &res.status { + TxStatus::Success { receipts } => receipts, + _ => return false, + }; + + let log_data_receipts = Self::filter_logdata_rec(receipts); + + match log_data_receipts.len() { + DISPATCH_LOG_DATA_REC_AMOUNT => true, + _ => false, + } + } + + /// Check if a transaction is a call to the post dispatch function of the MerkleTreeHook contract + fn is_merkle_tree_insertion(res: &TransactionResponse) -> bool { + let receipts = match &res.status { + TxStatus::Success { receipts } => receipts, + _ => return false, + }; + + let log_data_receipts = Self::filter_logdata_rec(receipts); + + // Merkle tree insertion is the only function which has a single log data receipt + match log_data_receipts.len() { + 1 => true, + _ => false, + } + } + + /// Check if a transaction is a call to the pay_for_gas function of the IGP Hook contract + fn is_igp_payment(res: &TransactionResponse) -> bool { + let receipts = match &res.status { + TxStatus::Success { receipts } => receipts, + _ => return false, + }; + + let log_data_receipts = Self::filter_logdata_rec(receipts); + + assert!( + log_data_receipts.len() == 1, + "IGP payment should have 1 log data receipt" + ); + let log = log_data_receipts.get(0).unwrap(); + + match log { + Receipt::LogData { data, .. } => data + .to_owned() + .is_some_and(|data| data.len() == IGP_PAYMENT_LOG_LENGTH), + _ => false, + } + } + + /// Retrieve only the logdata receipts + fn filter_logdata_rec(receipts: &Vec) -> Vec<&Receipt> { + receipts + .into_iter() + .filter(|rec| match rec { + Receipt::LogData { .. } => true, + _ => false, + }) + .collect::>() + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs index 3385872c35..1ffd2f26c6 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs @@ -1,37 +1,177 @@ -use std::ops::RangeInclusive; - +use crate::{ + contracts::interchain_gas_paymaster::InterchainGasPaymaster as InterchainGasPaymasterContract, + conversions::*, FuelProvider, +}; +use crate::{ConnectionConf, FuelIndexer, TransactionEventType}; use async_trait::async_trait; +use fuels::accounts::wallet::WalletUnlocked; +use fuels::tx::Receipt; +use fuels::types::bech32::Bech32ContractId; +use fuels::types::transaction_response::TransactionResponse; +use fuels::types::tx_status::TxStatus; +use fuels::types::{Bits256, Bytes32}; +use std::ops::RangeInclusive; use hyperlane_core::{ - ChainResult, HyperlaneChain, HyperlaneContract, Indexed, Indexer, InterchainGasPaymaster, + ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, Indexed, Indexer, + InterchainGasPaymaster, SequenceAwareIndexer, U256, }; use hyperlane_core::{HyperlaneDomain, HyperlaneProvider, InterchainGasPayment, LogMeta, H256}; /// A reference to an IGP contract on some Fuel chain #[derive(Debug)] -pub struct FuelInterchainGasPaymaster {} +pub struct FuelInterchainGasPaymaster { + contract: InterchainGasPaymasterContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelInterchainGasPaymaster { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelInterchainGasPaymaster { + contract: InterchainGasPaymasterContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} impl HyperlaneContract for FuelInterchainGasPaymaster { fn address(&self) -> H256 { - todo!() + self.contract.contract_id().into_h256() } } impl HyperlaneChain for FuelInterchainGasPaymaster { fn domain(&self) -> &HyperlaneDomain { - todo!() + &self.domain } fn provider(&self) -> Box { - todo!() + Box::new(self.provider.clone()) } } impl InterchainGasPaymaster for FuelInterchainGasPaymaster {} +// ---------------------------------------------------------- +// ---------------------- Indexer --------------------------- +// ---------------------------------------------------------- + +const IGP_PAYMENT_LOG_LENGTH: usize = 48; + /// Struct that retrieves event data for a Fuel IGP contract #[derive(Debug)] -pub struct FuelInterchainGasPaymasterIndexer {} +pub struct FuelInterchainGasPaymasterIndexer { + indexer: FuelIndexer, +} + +impl FuelInterchainGasPaymasterIndexer { + /// Create a new fuel IGP indexer + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + wallet: WalletUnlocked, + ) -> ChainResult { + let indexer = + FuelIndexer::new(conf, locator, wallet, TransactionEventType::IgpPayment).await; + + Ok(Self { indexer }) + } + + /// Parses igp payment transactions into the appropriate data to generate indexed logs + pub fn igp_parser( + transactions: Vec<(Bytes32, TransactionResponse)>, + ) -> Vec<(Bytes32, TransactionResponse, InterchainGasPayment, U256)> { + transactions + .into_iter() + .filter_map(|(tx_id, tx_data)| { + let receipts = match &tx_data.status { + TxStatus::Success { receipts } => receipts, + _ => return None, + }; + + let (log_index, receipt_log_data) = receipts + .into_iter() + .enumerate() + .filter_map(|(log_index, rec)| match rec { + Receipt::LogData { .. } + if rec + .data() + .is_some_and(|data| data.len() == IGP_PAYMENT_LOG_LENGTH) => + { + let data = rec.data().map(|data| data.to_owned()); + + match data { + Some(data) => Some((U256::from(log_index), data)), + _ => None, + } + } + _ => None, + }) + .next()?; // Each dispatch call should have only one receipt with the appropriate length + + if !receipt_log_data.is_empty() { + let (message_id, destination_domain, gas_amount, payment) = + Self::decode_interchain_gas_payment(receipt_log_data).unwrap(); + + let igp_payment = InterchainGasPayment { + message_id: message_id.into_h256(), + gas_amount: U256::from(gas_amount), + payment: U256::from(payment), + destination: destination_domain, + }; + + Some((tx_id, tx_data, igp_payment, log_index)) + } else { + None + } + }) + .collect::>() + } + + fn decode_interchain_gas_payment(data: Vec) -> Result<(Bits256, u32, u64, u64), String> { + if data.len() != 52 { + return Err("Invalid data length".to_owned()); + } + + // Extract message_id (first 32 bytes) + let message_id_bytes: [u8; 32] = data[0..32] + .try_into() + .map_err(|_| "Failed to extract message_id")?; + let message_id = Bits256(message_id_bytes); + + // Extract destination domain (next 4 bytes) + let destination_domain_bytes: [u8; 4] = data[32..36] + .try_into() + .map_err(|_| "Failed to extract destination_domain")?; + let destination_domain = u32::from_be_bytes(destination_domain_bytes); + + // Extract gas_amount (next 8 bytes) + let gas_amount_bytes: [u8; 8] = data[32..40] + .try_into() + .map_err(|_| "Failed to extract gas_amount")?; + let gas_amount = u64::from_be_bytes(gas_amount_bytes); + + // Extract payment (final 8 bytes) + let payment_bytes: [u8; 8] = data[40..48] + .try_into() + .map_err(|_| "Failed to extract payment")?; + let payment = u64::from_be_bytes(payment_bytes); + + Ok((message_id, destination_domain, gas_amount, payment)) + } +} #[async_trait] impl Indexer for FuelInterchainGasPaymasterIndexer { @@ -39,10 +179,21 @@ impl Indexer for FuelInterchainGasPaymasterIndexer { &self, range: RangeInclusive, ) -> ChainResult, LogMeta)>> { - todo!() + self.indexer + .index_logs_in_range(range, Self::igp_parser) + .await } async fn get_finalized_block_number(&self) -> ChainResult { - todo!() + self.indexer.provider().get_finalized_block_number().await + } +} + +#[async_trait] +impl SequenceAwareIndexer for FuelInterchainGasPaymasterIndexer { + async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { + // TODO: implement when fuel scraper support is implemented + let tip = self.get_finalized_block_number().await?; + Ok((None, tip)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs new file mode 100644 index 0000000000..69f4940964 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -0,0 +1,84 @@ +use crate::{ + contracts::interchain_security_module::InterchainSecurityModule as InterchainSecurityModuleContract, + conversions::*, ConnectionConf, FuelProvider, +}; +use async_trait::async_trait; +use fuels::{ + accounts::wallet::WalletUnlocked, programs::calls::Execution, types::bech32::Bech32ContractId, +}; +use hyperlane_core::{ + ChainCommunicationError, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, + HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, InterchainSecurityModule, ModuleType, + H256, U256, +}; + +/// A reference to a AggregationIsm contract on some Fuel chain +#[derive(Debug)] +pub struct FuelInterchainSecurityModule { + contract: InterchainSecurityModuleContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelInterchainSecurityModule { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelInterchainSecurityModule { + contract: InterchainSecurityModuleContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} + +impl HyperlaneContract for FuelInterchainSecurityModule { + fn address(&self) -> H256 { + self.contract.contract_id().into_h256() + } +} + +impl HyperlaneChain for FuelInterchainSecurityModule { + fn domain(&self) -> &HyperlaneDomain { + &self.domain + } + + fn provider(&self) -> Box { + Box::new(self.provider.clone()) + } +} + +#[async_trait] +impl InterchainSecurityModule for FuelInterchainSecurityModule { + async fn module_type(&self) -> ChainResult { + self.contract + .methods() + .module_type() + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| IsmType(res.value).into()) + } + + async fn dry_run_verify( + &self, + message: &HyperlaneMessage, + metadata: &[u8], + ) -> ChainResult> { + self.contract + .methods() + .module_type() + .simulate(Execution::Realistic) + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| Some(U256::from(res.gas_used))) + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/lib.rs b/rust/main/chains/hyperlane-fuel/src/lib.rs index 949387870a..c7659b67e4 100644 --- a/rust/main/chains/hyperlane-fuel/src/lib.rs +++ b/rust/main/chains/hyperlane-fuel/src/lib.rs @@ -6,14 +6,19 @@ #![allow(unused_variables)] pub use self::{ - interchain_gas::*, mailbox::*, multisig_ism::*, provider::*, routing_ism::*, trait_builder::*, + aggregation_ism::*, indexer::*, interchain_gas::*, interchain_security_module::*, mailbox::*, + merkle_tree_hook::*, multisig_ism::*, provider::*, routing_ism::*, trait_builder::*, validator_announce::*, }; +mod aggregation_ism; mod contracts; mod conversions; +mod indexer; mod interchain_gas; +mod interchain_security_module; mod mailbox; +mod merkle_tree_hook; mod multisig_ism; mod provider; mod routing_ism; diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 3df6bdc9e2..924488d110 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -1,11 +1,16 @@ use crate::{ - contracts::mailbox::Mailbox as FuelMailboxInner, conversions::*, ConnectionConf, FuelProvider, + contracts::mailbox::Mailbox as FuelMailboxContract, conversions::*, ConnectionConf, + FuelIndexer, FuelProvider, TransactionEventType, }; use async_trait::async_trait; use fuels::{ prelude::{Bech32ContractId, WalletUnlocked}, + programs::{calls::Execution, contract}, tx::{Receipt, ScriptExecutionResult}, - types::{transaction::TxPolicies, Bytes}, + types::{ + transaction::TxPolicies, transaction_response::TransactionResponse, tx_status::TxStatus, + Bytes, Bytes32, + }, }; use hyperlane_core::{ utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, @@ -23,7 +28,7 @@ use tracing::{instrument, warn}; /// A reference to a Mailbox contract on some Fuel chain pub struct FuelMailbox { - contract: FuelMailboxInner, + contract: FuelMailboxContract, provider: FuelProvider, domain: HyperlaneDomain, } @@ -41,7 +46,7 @@ impl FuelMailbox { let address = Bech32ContractId::from_h256(&locator.address); Ok(FuelMailbox { - contract: FuelMailboxInner::new(address, wallet), + contract: FuelMailboxContract::new(address, wallet), domain: locator.domain.clone(), provider: fuel_provider, }) @@ -82,7 +87,7 @@ impl Mailbox for FuelMailbox { self.contract .methods() .nonce() - .simulate() + .simulate(Execution::StateReadOnly) .await .map(|r| r.value) .map_err(ChainCommunicationError::from_other) @@ -94,7 +99,7 @@ impl Mailbox for FuelMailbox { self.contract .methods() .delivered(fuels::types::Bits256::from_h256(&id)) - .simulate() + .simulate(Execution::StateReadOnly) .await .map(|r| r.value) .map_err(ChainCommunicationError::from_other) @@ -106,7 +111,7 @@ impl Mailbox for FuelMailbox { self.contract .methods() .default_ism() - .simulate() + .simulate(Execution::StateReadOnly) .await .map(|r| r.value.into_h256()) .map_err(ChainCommunicationError::from_other) @@ -118,7 +123,7 @@ impl Mailbox for FuelMailbox { self.contract .methods() .recipient_ism(Bech32ContractId::from_h256(&recipient)) - .simulate() + .simulate(Execution::StateReadOnly) .await .map(|r| r.value.into_h256()) .map_err(ChainCommunicationError::from_other) @@ -219,11 +224,17 @@ impl Mailbox for FuelMailbox { } } +// ---------------------------------------------------------- +// ---------------------- Indexer --------------------------- +// ---------------------------------------------------------- + +const NON_DISPATCH_LOG_LEN: usize = 32; +const NON_HYP_MESSAGE_BYTES: usize = 76; /// Struct that retrieves event data for a Fuel Mailbox contract #[derive(Debug)] pub struct FuelMailboxIndexer { - contract: FuelMailboxInner, - provider: FuelProvider, + indexer: FuelIndexer, + contract: FuelMailboxContract, } impl FuelMailboxIndexer { @@ -233,15 +244,60 @@ impl FuelMailboxIndexer { locator: ContractLocator<'_>, wallet: WalletUnlocked, ) -> ChainResult { - let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + let contract = FuelMailboxContract::new( + Bech32ContractId::from_h256(&locator.address), + wallet.clone(), + ); + let indexer = + FuelIndexer::new(conf, locator, wallet, TransactionEventType::MailboxDispatch).await; - let address = Bech32ContractId::from_h256(&locator.address); - let contract = FuelMailboxInner::new(address, wallet); + Ok(Self { indexer, contract }) + } - Ok(FuelMailboxIndexer { - contract, - provider: fuel_provider, - }) + pub fn mailbox_parser( + transactions: Vec<(Bytes32, TransactionResponse)>, + ) -> Vec<(Bytes32, TransactionResponse, HyperlaneMessage, U256)> { + transactions + .into_iter() + .filter_map(|(tx_id, tx_data)| { + let receipts = match &tx_data.status { + TxStatus::Success { receipts } => receipts, + _ => return None, + }; + + let (log_index, mut receipt_log_data) = receipts + .into_iter() + .enumerate() + .filter_map(|(log_index, rec)| { + // We only care about LogData receipts with data length greater than 32 bytes + match rec { + Receipt::LogData { .. } + if rec + .data() + .is_some_and(|data| data.len() > NON_DISPATCH_LOG_LEN) => + { + let data = rec.data().map(|data| data.to_owned()); + + match data { + Some(data) => Some((U256::from(log_index), data)), + _ => None, + } + } + _ => None, + } + }) + .next()?; // Each dispatch call should have only one receipt with the appropriate length + + if !receipt_log_data.is_empty() { + // We cut out the message id, recipient and domain which are encoded in the first 76 bytes + receipt_log_data.drain(0..NON_HYP_MESSAGE_BYTES); + let encoded_message = HyperlaneMessage::from(receipt_log_data); + Some((tx_id, tx_data, encoded_message, log_index)) + } else { + None + } + }) + .collect::>() } } @@ -251,14 +307,13 @@ impl Indexer for FuelMailboxIndexer { &self, range: RangeInclusive, ) -> ChainResult, LogMeta)>> { - let mailbox_address = self.contract.contract_id().clone(); - self.provider - .index_logs_in_range(range, mailbox_address) + self.indexer + .index_logs_in_range(range, Self::mailbox_parser) .await } async fn get_finalized_block_number(&self) -> ChainResult { - self.provider.get_finalized_block_number().await + self.indexer.provider().get_finalized_block_number().await } } @@ -272,7 +327,7 @@ impl Indexer for FuelMailboxIndexer { } async fn get_finalized_block_number(&self) -> ChainResult { - self.provider.get_finalized_block_number().await + self.indexer.provider().get_finalized_block_number().await } } @@ -295,7 +350,7 @@ impl SequenceAwareIndexer for FuelMailboxIndexer { self.contract .methods() .nonce() - .simulate() + .simulate(Execution::StateReadOnly) .await .map(|r| r.value) .map_err(ChainCommunicationError::from_other) diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs new file mode 100644 index 0000000000..25599c53a2 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -0,0 +1,241 @@ +use std::{num::NonZeroU64, ops::RangeInclusive}; + +use crate::{ + contracts::merkle_tree_hook::MerkleTreeHook as MerkleTreeHookContract, conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, TransactionEventType, +}; +use async_trait::async_trait; +use fuels::{ + accounts::wallet::WalletUnlocked, + tx::Receipt, + types::{ + bech32::Bech32ContractId, transaction_response::TransactionResponse, tx_status::TxStatus, + Bytes32, + }, +}; +use hyperlane_core::{ + accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint, + ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneIdentifier, + HyperlaneProvider, Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, + SequenceAwareIndexer, H256, U256, +}; + +/// A reference to a AggregationIsm contract on some Fuel chain +#[derive(Debug)] +pub struct FuelMerkleTreeHook { + contract: MerkleTreeHookContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelMerkleTreeHook { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelMerkleTreeHook { + contract: MerkleTreeHookContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} + +impl HyperlaneContract for FuelMerkleTreeHook { + fn address(&self) -> H256 { + self.contract.contract_id().into_h256() + } +} + +impl HyperlaneChain for FuelMerkleTreeHook { + fn domain(&self) -> &HyperlaneDomain { + &self.domain + } + + fn provider(&self) -> Box { + Box::new(self.provider.clone()) + } +} + +#[async_trait] +impl MerkleTreeHook for FuelMerkleTreeHook { + async fn tree(&self, lag: Option) -> ChainResult { + assert!( + lag.is_none(), + "Fuel does not support querying point-in-time" + ); + + self.contract + .methods() + .tree() + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| { + let merkle_tree = res.value; + IncrementalMerkle { + branch: merkle_tree.branch.into_h256_array(), + count: merkle_tree.count as usize, + } + }) + } + + async fn count(&self, lag: Option) -> ChainResult { + assert!( + lag.is_none(), + "Fuel does not support querying point-in-time" + ); + + self.contract + .methods() + .count() + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| res.value) + } + + async fn latest_checkpoint(&self, lag: Option) -> ChainResult { + assert!( + lag.is_none(), + "Fuel does not support querying point-in-time" + ); + + self.contract + .methods() + .latest_checkpoint() + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| { + let (root, count) = res.value; + Checkpoint { + root: root.into_h256(), + index: count, + merkle_tree_hook_address: self.address(), + mailbox_domain: self.domain.id(), + } + }) + } +} + +// ---------------------------------------------------------- +// ---------------------- Indexer --------------------------- +// ---------------------------------------------------------- + +const MESSAGE_ID_LEN: usize = 32; + +/// Struct that retrieves event data for a Fuel MerkleTreeHook contract +#[derive(Debug)] +pub struct FuelMerkleTreeHookIndexer { + indexer: FuelIndexer, + contract: MerkleTreeHookContract, +} + +impl FuelMerkleTreeHookIndexer { + /// Create a new fuel MerkleTreeHook indexer + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + wallet: WalletUnlocked, + ) -> ChainResult { + let contract = MerkleTreeHookContract::new( + Bech32ContractId::from_h256(&locator.address), + wallet.clone(), + ); + let indexer = FuelIndexer::new( + conf, + locator, + wallet, + TransactionEventType::MerkleTreeHookInsert, + ) + .await; + + Ok(Self { indexer, contract }) + } + + /// Parses merkle tree hook post dispatch transactions into the appropriate data to generate indexed logs + pub fn merkle_tree_hook_parser( + transactions: Vec<(Bytes32, TransactionResponse)>, + ) -> Vec<(Bytes32, TransactionResponse, MerkleTreeInsertion, U256)> { + transactions + .into_iter() + .filter_map(|(tx_id, tx_data)| { + let receipts = match &tx_data.status { + TxStatus::Success { receipts } => receipts, + _ => return None, + }; + + let (log_index, receipt_log_data) = receipts + .into_iter() + .enumerate() + .filter_map(|(log_index, rec)| match rec { + Receipt::LogData { .. } if rec.data().is_some() => { + let data = rec.data().map(|data| data.to_owned()); + + match data { + Some(data) => Some((U256::from(log_index), data)), + _ => None, + } + } + _ => None, + }) + .next()?; // Each merkle tree hook post dispatch call should have only one logdata receipt + + if !receipt_log_data.is_empty() { + // The log is strucutred to have a message id first and the leaf index following it + let (id, index) = receipt_log_data.split_at(MESSAGE_ID_LEN); + let message_id = + H256::from(<[u8; 32]>::try_from(id).expect("slice with incorrect length")); + let leaf_index = + u32::from_be_bytes(index.try_into().expect("slice with incorrect length")); + + let insertion = MerkleTreeInsertion::new(leaf_index, message_id); + + Some((tx_id, tx_data, insertion, log_index)) + } else { + None + } + }) + .collect::>() + } +} + +#[async_trait] +impl Indexer for FuelMerkleTreeHookIndexer { + /// Fetch list of logs between `range` of blocks + async fn fetch_logs_in_range( + &self, + range: RangeInclusive, + ) -> ChainResult, LogMeta)>> { + self.indexer + .index_logs_in_range(range, Self::merkle_tree_hook_parser) + .await + } + + /// Get the chain's latest block number that has reached finality + async fn get_finalized_block_number(&self) -> ChainResult { + self.indexer.provider().get_finalized_block_number().await + } +} + +#[async_trait] +impl SequenceAwareIndexer for FuelMerkleTreeHookIndexer { + async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { + let tip = self.get_finalized_block_number().await?; + self.contract + .methods() + .count() + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| (Some(res.value), tip)) + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs index 0289a67005..f8d95593bd 100644 --- a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs @@ -1,27 +1,58 @@ +use crate::{ + contracts::multisig_ism::MultisigISM as MultisigIsmContract, conversions::*, ConnectionConf, + FuelProvider, +}; use async_trait::async_trait; - +use fuels::{ + accounts::wallet::WalletUnlocked, + types::{bech32::Bech32ContractId, Bytes}, +}; use hyperlane_core::{ - ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, - HyperlaneProvider, MultisigIsm, H256, + ChainCommunicationError, ChainResult, ContractLocator, Encode, HyperlaneChain, + HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, MultisigIsm, H256, }; /// A reference to a MultisigIsm contract on some Fuel chain #[derive(Debug)] -pub struct FuelMultisigIsm {} +pub struct FuelMultisigIsm { + contract: MultisigIsmContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelMultisigIsm { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelMultisigIsm { + contract: MultisigIsmContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} impl HyperlaneContract for FuelMultisigIsm { fn address(&self) -> H256 { - todo!() + self.contract.contract_id().into_h256() } } impl HyperlaneChain for FuelMultisigIsm { fn domain(&self) -> &HyperlaneDomain { - todo!() + &self.domain } fn provider(&self) -> Box { - todo!() + Box::new(self.provider.clone()) } } @@ -32,6 +63,12 @@ impl MultisigIsm for FuelMultisigIsm { &self, message: &HyperlaneMessage, ) -> ChainResult<(Vec, u8)> { - todo!() + self.contract + .methods() + .validators_and_threshold(Bytes(message.to_vec())) + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| (res.value.0.into_h256_vec(), res.value.1)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index e3836f141a..e1614c2039 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -1,29 +1,18 @@ -use std::{collections::HashMap, ops::Deref}; +use std::io::Read; +use crate::{make_client, make_provider, ConnectionConf}; use async_trait::async_trait; - use fuels::{ - client::{FuelClient, PageDirection, PaginationRequest}, + client::FuelClient, prelude::Provider, tx::Receipt, - types::{ - bech32::Bech32ContractId, - block::Block, - gas_price::LatestGasPrice, - transaction::{Transaction, TransactionType}, - transaction_response::TransactionResponse, - tx_status::TxStatus, - Address, Bytes32, ContractId, - }, + types::{transaction::TransactionType, tx_status::TxStatus, Address, ContractId}, }; -use futures::future::join_all; use hyperlane_core::{ BlockInfo, ChainCommunicationError, ChainInfo, ChainResult, HyperlaneChain, HyperlaneDomain, - HyperlaneMessage, HyperlaneProvider, Indexed, LogMeta, TxnInfo, H256, H512, U256, + HyperlaneProvider, HyperlaneProviderError, TxnInfo, H256, U256, }; -use crate::{make_client, make_provider, prelude::FuelIntoH256, ConnectionConf}; - /// A wrapper around a fuel provider to get generic blockchain information. #[derive(Debug, Clone)] pub struct FuelProvider { @@ -52,223 +41,20 @@ impl FuelProvider { /// Get the latest gas price pub async fn get_gas_price(&self) -> ChainResult { - let LatestGasPrice { gas_price, .. } = self - .provider() + self.provider .latest_gas_price() .await - .map_err(ChainCommunicationError::from_other)?; - - Ok(gas_price) - } - - /// Check if a transaction is from a contract - /// @note: Only works for checking script transactions - /// Assumes that the first input is the contract id - #[allow(clippy::get_first)] // TODO: `rustc` 1.80.1 clippy issue - fn is_transaction_from_contract( - res: &TransactionResponse, - contract: &Bech32ContractId, - ) -> bool { - if let TransactionType::Script(script_transaction) = &res.transaction { - if script_transaction.inputs().get(0).is_some_and(|input| { - input - .contract_id() - .is_some_and(|id| id == &ContractId::from(&contract.into())) - }) { - return true; - } - } - false - } - - /// Check if a transaction is a call to the dispatch function of the Mailbox contract - #[allow(clippy::match_like_matches_macro)] // TODO: `rustc` 1.80.1 clippy issue - #[allow(clippy::into_iter_on_ref)] // TODO: `rustc` 1.80.1 clippy issue - fn is_dispatch_call(res: &TransactionResponse) -> bool { - // let selector = encode_fn_selector("dispatch"); - // println!("selector: {:?}", selector); // XXX see if we can get the correct txn by selector - // Apparently we should be able to see it in the call logs - - let receipts = match &res.status { - TxStatus::Success { receipts } => receipts, - _ => return false, - }; - let log_data_receipts = receipts - .into_iter() - .filter(|rec| { - // if let Receipt::Call { param1, param2, .. } = rec { - // print!( - // "param1: {:?}, param2: {:?}", - // param1.to_be_bytes(), - // param2.to_be_bytes() - // ); - // } - - match rec { - Receipt::LogData { .. } => true, - _ => false, - } - }) - .collect::>(); - - // Dispatch is the only call that has 2 log data receipts - match log_data_receipts.len() { - 2 => true, - _ => false, - } - } - - #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue - async fn get_block_data( - &self, - range: std::ops::RangeInclusive, - ) -> ChainResult<(Vec, HashMap)> { - let result_amount = range.end() - range.start() + 1; - let req = PaginationRequest { - cursor: Some(range.start().to_string()), - results: i32::try_from(result_amount).expect("Invalid range"), - direction: PageDirection::Forward, - }; - - let blocks = self - .provider - .get_blocks(req) - .await - .map_err(ChainCommunicationError::from_other)?; - - let mut transaction_map: HashMap = HashMap::new(); - blocks.results.iter().for_each(|block| { - block - .transactions - .iter() - .enumerate() - .for_each(|(index, tx)| { - transaction_map.insert(tx.clone(), (block.id, index as u64)); - }); - }); - Ok((blocks.results, transaction_map)) + .map_err(ChainCommunicationError::from_other) + .map(|res| res.gas_price) } /// Get the finalized block number - /// XXX might be inaccurate as we do not know the block finality pub async fn get_finalized_block_number(&self) -> ChainResult { self.provider .latest_block_height() .await .map_err(ChainCommunicationError::from_other) } - - /// index logs in a range - #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue - #[allow(clippy::manual_map)] // TODO: `rustc` 1.80.1 clippy issue - #[allow(clippy::into_iter_on_ref)] // TODO: `rustc` 1.80.1 clippy issue - #[allow(clippy::needless_borrow)] // TODO: `rustc` 1.80.1 clippy issue - pub async fn index_logs_in_range( - &self, - range: std::ops::RangeInclusive, - mailbox_contract: Bech32ContractId, - ) -> ChainResult, LogMeta)>> { - let (blocks, transaction_map) = self.get_block_data(range.clone()).await.unwrap(); - - // Transaction ids from selected blocks - let transaction_ids = blocks - .into_iter() - .map(|block| block.transactions) - .flat_map(|txs| txs.into_iter()) - .collect::>(); - - let futures = transaction_ids - .into_iter() - .map(|tx_id| { - let provider = self.provider.clone(); - let tx_clone = tx_id.clone(); - async move { - let result = provider.get_transaction_by_id(&tx_id).await.unwrap(); - (tx_clone, result) - } - }) - .collect::>(); - - // Filter transactions - // 1. Transaction type is Script - // 2. Transaction status is Success - // 3. Transaction is from mailbox contract - // 4. Transaction is a dispatch call - // 5. Transaction data is valid - let transaction_data = join_all(futures) - .await - .into_iter() - .filter_map(|(tx_id, tx_data)| match tx_data { - Some(tx_data) => Some((tx_id, tx_data)), - _ => None, - }) - .filter(|(_, tx_data)| { - matches!(tx_data.transaction, TransactionType::Script(_)) - && matches!(tx_data.status, TxStatus::Success { .. }) - && Self::is_transaction_from_contract(&tx_data, &mailbox_contract) - && Self::is_dispatch_call(&tx_data) - }) - .collect::>(); - - // Full data needed to construct the logs - let full_tx_data = transaction_data - .into_iter() - .filter_map(|(tx_id, tx_data)| { - let receipts = match &tx_data.status { - TxStatus::Success { receipts } => receipts, - _ => return None, - }; - - let (log_index, mut receipt_log_data) = receipts - .into_iter() - .enumerate() - .filter_map(|(log_index, rec)| { - // We only care about LogData receipts with data length greater than 32 bytes - match rec { - Receipt::LogData { .. } - if rec.data().is_some_and(|data| data.len() > 32) => - { - let data = rec.data().map(|data| data.to_owned()); - - match data { - Some(data) => Some((U256::from(log_index), data)), - _ => None, - } - } - _ => None, - } - }) - .next()?; // Each dispatch call should have only one log data receipt - - if !receipt_log_data.is_empty() { - // We cut out the message id, recipient and domain which are encoded in the first 76 bytes - receipt_log_data.drain(0..76); - let encoded_message = HyperlaneMessage::from(receipt_log_data); - Some((tx_id, tx_data, encoded_message, log_index)) - } else { - None - } - }) - .collect::>(); // Collect all Vec from each transaction into a Vec> - - let indexed_logs: Vec<(Indexed, LogMeta)> = full_tx_data - .into_iter() - .map(|(tx_id, tx, message, log_index)| { - let (block_hash, transaction_index) = transaction_map.get(&tx_id).unwrap(); - - let log_meta = LogMeta { - address: mailbox_contract.clone().into_h256(), - block_number: *tx.block_height.unwrap().deref() as u64, - block_hash: block_hash.into_h256(), - transaction_id: H512::from(tx_id.into_h256()), - transaction_index: transaction_index.clone(), - log_index, - }; - (message.into(), log_meta) - }) - .collect::>(); - Ok(indexed_logs) - } } impl HyperlaneChain for FuelProvider { @@ -286,9 +72,11 @@ impl HyperlaneProvider for FuelProvider { /// Used by scraper #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue async fn get_block_by_hash(&self, hash: &H256) -> ChainResult { - let block_res = self.provider.block(&hash.0.into()).await.map_err(|e| { - ChainCommunicationError::CustomError(format!("Failed to get block: {}", e)) - })?; + let block_res = self + .provider + .block(&hash.0.into()) + .await + .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(hash.clone()))?; match block_res { Some(block) => Ok(BlockInfo { @@ -308,9 +96,7 @@ impl HyperlaneProvider for FuelProvider { .provider .get_transaction_by_id(&hash.0.into()) .await - .map_err(|e| { - ChainCommunicationError::CustomError(format!("Failed to get transaction: {}", e)) - })?; + .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(hash.clone()))?; match transaction_res { Some(transaction) => { @@ -391,10 +177,12 @@ impl HyperlaneProvider for FuelProvider { async fn get_balance(&self, address: String) -> ChainResult { let base = self.provider.base_asset_id(); - let asset = *Address::from_bytes_ref_checked(address.as_bytes()).expect("Invalid address"); + let address_bytes = hex::decode(address)?; + let address = + *Address::from_bytes_ref_checked(address_bytes.as_slice()).expect("Invalid address"); self.provider - .get_asset_balance(&asset.into(), *base) + .get_asset_balance(&address.into(), *base) .await .map(|balance| Ok(U256::from(balance))) .map_err(|e| { diff --git a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs index 9c1c10c97d..5ce81747f1 100644 --- a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs @@ -1,27 +1,58 @@ +use crate::{ + contracts::routing_ism::RoutingISM as RoutingISMContract, conversions::*, ConnectionConf, + FuelProvider, +}; use async_trait::async_trait; - +use fuels::{ + accounts::wallet::WalletUnlocked, + types::{bech32::Bech32ContractId, Bytes}, +}; use hyperlane_core::{ - ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, - HyperlaneProvider, RoutingIsm, H256, + ChainCommunicationError, ChainResult, ContractLocator, Encode, HyperlaneChain, + HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, RoutingIsm, H256, }; /// A reference to a RoutingIsm contract on some Fuel chain #[derive(Debug)] -pub struct FuelRoutingIsm {} +pub struct FuelRoutingIsm { + contract: RoutingISMContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelRoutingIsm { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelRoutingIsm { + contract: RoutingISMContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} impl HyperlaneContract for FuelRoutingIsm { fn address(&self) -> H256 { - todo!() + self.contract.contract_id().into_h256() } } impl HyperlaneChain for FuelRoutingIsm { fn domain(&self) -> &HyperlaneDomain { - todo!() + &self.domain } fn provider(&self) -> Box { - todo!() + Box::new(self.provider.clone()) } } @@ -29,6 +60,12 @@ impl HyperlaneChain for FuelRoutingIsm { impl RoutingIsm for FuelRoutingIsm { /// Returns the ism needed to verify message async fn route(&self, message: &HyperlaneMessage) -> ChainResult { - todo!() + self.contract + .methods() + .route(Bytes(message.to_vec())) + .call() + .await + .map_err(ChainCommunicationError::from_other) + .map(|res| res.value.into_h256()) } } diff --git a/rust/main/chains/hyperlane-fuel/src/trait_builder.rs b/rust/main/chains/hyperlane-fuel/src/trait_builder.rs index b9efd90600..0a6965028b 100644 --- a/rust/main/chains/hyperlane-fuel/src/trait_builder.rs +++ b/rust/main/chains/hyperlane-fuel/src/trait_builder.rs @@ -1,5 +1,5 @@ use fuels::{client::FuelClient, prelude::Provider}; -use hyperlane_core::{ChainCommunicationError, ChainResult}; +use hyperlane_core::{config::OperationBatchConfig, ChainCommunicationError, ChainResult}; use url::Url; /// Fuel connection configuration @@ -7,6 +7,7 @@ use url::Url; pub struct ConnectionConf { /// Fully qualified string to connect to pub url: Url, + pub operation_batch: OperationBatchConfig, } /// An error type when parsing a connection configuration. diff --git a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs index 10402db4b4..3c8d53c931 100644 --- a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs +++ b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs @@ -1,27 +1,61 @@ +use crate::{ + contracts::validator_announce::ValidatorAnnounce as FuelVAContract, conversions::*, + ConnectionConf, FuelProvider, +}; use async_trait::async_trait; - +use fuels::{ + prelude::WalletUnlocked, + tx::{Receipt, ScriptExecutionResult}, + types::{bech32::Bech32ContractId, Address, Bits256, Bytes}, +}; use hyperlane_core::{ - Announcement, ChainResult, HyperlaneChain, HyperlaneContract, HyperlaneDomain, - HyperlaneProvider, SignedType, TxOutcome, ValidatorAnnounce, H256, U256, + Announcement, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneChain, + HyperlaneContract, HyperlaneDomain, HyperlaneProvider, SignedType, TxOutcome, + ValidatorAnnounce, H256, H512, U256, }; +use tracing::trace; /// A reference to a ValidatorAnnounce contract on some Fuel chain #[derive(Debug)] -pub struct FuelValidatorAnnounce {} +pub struct FuelValidatorAnnounce { + contract: FuelVAContract, + domain: HyperlaneDomain, + provider: FuelProvider, +} + +impl FuelValidatorAnnounce { + /// Create a new fuel validator announce contract + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + mut wallet: WalletUnlocked, + ) -> ChainResult { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + + wallet.set_provider(fuel_provider.provider().clone()); + let address = Bech32ContractId::from_h256(&locator.address); + + Ok(FuelValidatorAnnounce { + contract: FuelVAContract::new(address, wallet), + domain: locator.domain.clone(), + provider: fuel_provider, + }) + } +} impl HyperlaneContract for FuelValidatorAnnounce { fn address(&self) -> H256 { - todo!() + self.contract.contract_id().into_h256() } } impl HyperlaneChain for FuelValidatorAnnounce { fn domain(&self) -> &HyperlaneDomain { - todo!() + &self.domain } fn provider(&self) -> Box { - todo!() + Box::new(self.provider.clone()) } } @@ -31,14 +65,77 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { &self, validators: &[H256], ) -> ChainResult>> { - todo!() + self.contract + .methods() + .get_announced_storage_locations( + validators.iter().map(|v| Bits256::from_h256(v)).collect(), + ) + .call() + .await + .map(|res| res.value) + .map_err(ChainCommunicationError::from_other) } async fn announce(&self, announcement: SignedType) -> ChainResult { - todo!() + let gas_price = self.provider.get_gas_price().await?; + let call_res = self + .contract + .methods() + .announce( + announcement.value.validator.into_evm_address(), + announcement.value.storage_location, + Bytes(announcement.signature.to_vec()), + ) + .call() + .await + .map_err(ChainCommunicationError::from_other)?; + + // Extract transaction success from the receipts + let success = call_res + .receipts + .iter() + .filter_map(|r| match r { + Receipt::ScriptResult { result, .. } => Some(result), + _ => None, + }) + .any(|result| matches!(result, ScriptExecutionResult::Success)); + + let tx_id = H512::from(call_res.tx_id.unwrap().into_h256()); + Ok(TxOutcome { + transaction_id: tx_id, + executed: success, + gas_used: call_res.gas_used.into(), + gas_price: gas_price.into(), + }) } async fn announce_tokens_needed(&self, announcement: SignedType) -> Option { - todo!() + let tolerance = Some(0.0); + let block_horizon = Some(1); + + let cost_estimation = self + .contract + .methods() + .announce( + announcement.value.validator.into_evm_address(), + announcement.value.storage_location, + Bytes(announcement.signature.to_vec()), + ) + .estimate_transaction_cost(tolerance, block_horizon) + .await; + + let signer = Address::from(self.contract.account().address()).to_string(); + let signer_balance = self.provider.get_balance(signer).await.unwrap(); + + match cost_estimation { + Ok(cost) => { + let max_cost = U256::from(cost.total_fee); + return Some(max_cost.saturating_sub(signer_balance)); + } + Err(err) => { + trace!("Failed to estimate transaction cost: {:?}", err); + return None; + } + } } } diff --git a/rust/main/hyperlane-base/src/contract_sync/cursors/mod.rs b/rust/main/hyperlane-base/src/contract_sync/cursors/mod.rs index 563d0fcc74..75db7d06e7 100644 --- a/rust/main/hyperlane-base/src/contract_sync/cursors/mod.rs +++ b/rust/main/hyperlane-base/src/contract_sync/cursors/mod.rs @@ -30,7 +30,7 @@ impl Indexable for HyperlaneMessage { fn indexing_cursor(domain: HyperlaneDomainProtocol) -> CursorType { match domain { HyperlaneDomainProtocol::Ethereum => CursorType::SequenceAware, - HyperlaneDomainProtocol::Fuel => todo!(), + HyperlaneDomainProtocol::Fuel => CursorType::SequenceAware, HyperlaneDomainProtocol::Sealevel => CursorType::SequenceAware, HyperlaneDomainProtocol::Cosmos => CursorType::SequenceAware, } @@ -46,7 +46,7 @@ impl Indexable for InterchainGasPayment { fn indexing_cursor(domain: HyperlaneDomainProtocol) -> CursorType { match domain { HyperlaneDomainProtocol::Ethereum => CursorType::RateLimited, - HyperlaneDomainProtocol::Fuel => todo!(), + HyperlaneDomainProtocol::Fuel => CursorType::RateLimited, HyperlaneDomainProtocol::Sealevel => CursorType::SequenceAware, HyperlaneDomainProtocol::Cosmos => CursorType::RateLimited, } @@ -57,7 +57,7 @@ impl Indexable for MerkleTreeInsertion { fn indexing_cursor(domain: HyperlaneDomainProtocol) -> CursorType { match domain { HyperlaneDomainProtocol::Ethereum => CursorType::SequenceAware, - HyperlaneDomainProtocol::Fuel => todo!(), + HyperlaneDomainProtocol::Fuel => CursorType::SequenceAware, HyperlaneDomainProtocol::Sealevel => CursorType::SequenceAware, HyperlaneDomainProtocol::Cosmos => CursorType::SequenceAware, } @@ -68,7 +68,7 @@ impl Indexable for Delivery { fn indexing_cursor(domain: HyperlaneDomainProtocol) -> CursorType { match domain { HyperlaneDomainProtocol::Ethereum => CursorType::RateLimited, - HyperlaneDomainProtocol::Fuel => todo!(), + HyperlaneDomainProtocol::Fuel => CursorType::RateLimited, HyperlaneDomainProtocol::Sealevel => CursorType::SequenceAware, HyperlaneDomainProtocol::Cosmos => CursorType::RateLimited, } diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index 34de1192a4..51cea7dbbb 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -1,5 +1,6 @@ use axum::async_trait; use ethers::prelude::Selector; +use fuels::accounts::wallet::WalletUnlocked; use h_cosmos::CosmosProvider; use std::{collections::HashMap, sync::Arc}; @@ -13,7 +14,7 @@ use hyperlane_core::{ MerkleTreeHook, MerkleTreeInsertion, MultisigIsm, RoutingIsm, SequenceAwareIndexer, ValidatorAnnounce, H256, }; -use hyperlane_cosmos as h_cosmos; +use hyperlane_cosmos::{self as h_cosmos}; use hyperlane_ethereum::{ self as h_eth, BuildableWithProvider, EthereumInterchainGasPaymasterAbi, EthereumMailboxAbi, EthereumValidatorAnnounceAbi, @@ -132,7 +133,7 @@ impl ChainConnectionConf { Self::Ethereum(conf) => Some(&conf.operation_batch), Self::Cosmos(conf) => Some(&conf.operation_batch), Self::Sealevel(conf) => Some(&conf.operation_batch), - _ => None, + Self::Fuel(conf) => Some(&conf.operation_batch), } } } @@ -179,7 +180,9 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::HyperlaneProviderBuilder {}) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => Ok(Box::new( + h_fuel::FuelProvider::new(locator.domain.clone(), conf).await, + ) as Box), ChainConnectionConf::Sealevel(conf) => Ok(Box::new(h_sealevel::SealevelProvider::new( locator.domain.clone(), conf, @@ -243,8 +246,12 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::MerkleTreeHookBuilder {}) .await } - ChainConnectionConf::Fuel(_conf) => { - todo!("Fuel does not support merkle tree hooks yet") + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + h_fuel::FuelMerkleTreeHook::new(conf, locator, wallet) + .await + .map(|m| Box::new(m) as Box) + .map_err(Into::into) } ChainConnectionConf::Sealevel(conf) => { h_sealevel::SealevelMailbox::new(conf, locator, None) @@ -282,7 +289,12 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + let indexer = + Box::new(h_fuel::FuelMailboxIndexer::new(conf, locator, wallet).await?); + Ok(indexer as Box>) + } ChainConnectionConf::Sealevel(conf) => { let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); Ok(indexer as Box>) @@ -321,7 +333,7 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(_) => todo!("Fuel does not have scraper support yet"), ChainConnectionConf::Sealevel(conf) => { let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); Ok(indexer as Box>) @@ -359,7 +371,13 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new(h_fuel::FuelInterchainGasPaymaster::new(conf, locator, wallet).await?) + as Box, + ) + } ChainConnectionConf::Sealevel(conf) => { let paymaster = Box::new( h_sealevel::SealevelInterchainGasPaymaster::new(conf, &locator).await?, @@ -400,7 +418,13 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + let indexer = Box::new( + h_fuel::FuelInterchainGasPaymasterIndexer::new(conf, locator, wallet).await?, + ); + Ok(indexer as Box>) + } ChainConnectionConf::Sealevel(conf) => { let indexer = Box::new( h_sealevel::SealevelInterchainGasPaymasterIndexer::new(conf, locator).await?, @@ -439,7 +463,12 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let signer = self.fuel_signer().await.context(ctx)?; + let indexer = + Box::new(h_fuel::FuelMerkleTreeHookIndexer::new(conf, locator, signer).await?); + Ok(indexer as Box>) + } ChainConnectionConf::Sealevel(conf) => { let mailbox_indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); @@ -475,7 +504,13 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::ValidatorAnnounceBuilder {}) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new(h_fuel::FuelValidatorAnnounce::new(conf, locator, wallet).await?) + as Box, + ) + } ChainConnectionConf::Sealevel(conf) => { let va = Box::new(h_sealevel::SealevelValidatorAnnounce::new(conf, locator)); Ok(va as Box) @@ -514,7 +549,14 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new( + h_fuel::FuelInterchainSecurityModule::new(conf, locator, wallet).await?, + ) as Box, + ) + } ChainConnectionConf::Sealevel(conf) => { let keypair = self.sealevel_signer().await.context(ctx)?; let ism = Box::new(h_sealevel::SealevelInterchainSecurityModule::new( @@ -547,8 +589,13 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::MultisigIsmBuilder {}) .await } - - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new(h_fuel::FuelMultisigIsm::new(conf, locator, wallet).await?) + as Box, + ) + } ChainConnectionConf::Sealevel(conf) => { let keypair = self.sealevel_signer().await.context(ctx)?; let ism = Box::new(h_sealevel::SealevelMultisigIsm::new(conf, locator, keypair)); @@ -584,7 +631,13 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::RoutingIsmBuilder {}) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new(h_fuel::FuelRoutingIsm::new(conf, locator, wallet).await?) + as Box, + ) + } ChainConnectionConf::Sealevel(_) => { Err(eyre!("Sealevel does not support routing ISM yet")).context(ctx) } @@ -618,7 +671,13 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::AggregationIsmBuilder {}) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + Ok( + Box::new(h_fuel::FuelAggregationIsm::new(conf, locator, wallet).await?) + as Box, + ) + } ChainConnectionConf::Sealevel(_) => { Err(eyre!("Sealevel does not support aggregation ISM yet")).context(ctx) } @@ -653,7 +712,9 @@ impl ChainConf { self.build_ethereum(conf, &locator, metrics, h_eth::CcipReadIsmBuilder {}) .await } - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(_) => { + Err(eyre!("Fuel does not support CCIP read ISM yet")).context(ctx) + } ChainConnectionConf::Sealevel(_) => { Err(eyre!("Sealevel does not support CCIP read ISM yet")).context(ctx) } @@ -696,9 +757,24 @@ impl ChainConf { } async fn fuel_signer(&self) -> Result { - self.signer().await.and_then(|opt| { - opt.ok_or_else(|| eyre!("Fuel requires a signer to construct contract instances")) - }) + let mut wallet: WalletUnlocked = self + .signer() + .await? + .ok_or_else(|| eyre!("Fuel requires a signer to construct contract instances"))?; + + let connection_conf = match &self.connection { + ChainConnectionConf::Fuel(conf) => conf, + _ => { + return Err(eyre!( + "The connection configuration for the chain is not a Fuel connection" + )) + } + }; + + let provider = h_fuel::make_provider(connection_conf).await?; + wallet.set_provider(provider); + + Ok(wallet) } async fn sealevel_signer(&self) -> Result> { diff --git a/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs b/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs index 4bc6a01b77..5ab96e1054 100644 --- a/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs +++ b/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs @@ -168,10 +168,12 @@ pub fn build_connection_conf( default_rpc_consensus_type, operation_batch, ), - HyperlaneDomainProtocol::Fuel => rpcs - .iter() - .next() - .map(|url| ChainConnectionConf::Fuel(h_fuel::ConnectionConf { url: url.clone() })), + HyperlaneDomainProtocol::Fuel => rpcs.iter().next().map(|url| { + ChainConnectionConf::Fuel(h_fuel::ConnectionConf { + url: url.clone(), + operation_batch, + }) + }), HyperlaneDomainProtocol::Sealevel => rpcs.iter().next().map(|url| { ChainConnectionConf::Sealevel(h_sealevel::ConnectionConf { url: url.clone(), diff --git a/rust/main/hyperlane-base/src/settings/signers.rs b/rust/main/hyperlane-base/src/settings/signers.rs index 042894c6b5..275403e8cc 100644 --- a/rust/main/hyperlane-base/src/settings/signers.rs +++ b/rust/main/hyperlane-base/src/settings/signers.rs @@ -114,7 +114,7 @@ impl BuildableWithSignerConf for fuels::prelude::WalletUnlocked { impl ChainSigner for fuels::prelude::WalletUnlocked { fn address_string(&self) -> String { - self.address().to_string() + fuels::types::Address::from(self.address()).to_string() } } diff --git a/rust/main/hyperlane-core/src/chain.rs b/rust/main/hyperlane-core/src/chain.rs index d1b7c5e349..6948dc6c21 100644 --- a/rust/main/hyperlane-core/src/chain.rs +++ b/rust/main/hyperlane-core/src/chain.rs @@ -125,6 +125,7 @@ pub enum KnownHyperlaneDomain { ScrollSepolia = 534351, Sepolia = 11155111, SuperpositionTestnet = 98985, + FuelTestnet = 1717982312, } #[derive(Clone, Serialize)] @@ -242,7 +243,7 @@ impl KnownHyperlaneDomain { ], Testnet: [ Alfajores, BinanceSmartChainTestnet, Chiado, ConnextSepolia, Fuji, Holesky, MoonbaseAlpha, - PlumeTestnet, ScrollSepolia, Sepolia, SuperpositionTestnet + PlumeTestnet, ScrollSepolia, Sepolia, SuperpositionTestnet, FuelTestnet ], LocalTestChain: [ Test1, Test2, Test3, FuelTest1, SealevelTest1, SealevelTest2, CosmosTest99990, @@ -270,7 +271,7 @@ impl KnownHyperlaneDomain { ScrollSepolia, Sepolia, SuperpositionTestnet ], - HyperlaneDomainProtocol::Fuel: [FuelTest1], + HyperlaneDomainProtocol::Fuel: [FuelTest1, FuelTestnet], HyperlaneDomainProtocol::Sealevel: [EclipseMainnet, SolanaMainnet, SealevelTest1, SealevelTest2], HyperlaneDomainProtocol::Cosmos: [ Injective, Neutron, Osmosis, @@ -300,7 +301,7 @@ impl KnownHyperlaneDomain { // Local chains CosmosTest99990, CosmosTest99991, FuelTest1, SealevelTest1, SealevelTest2, Test1, - Test2, Test3, + Test2, Test3, FuelTestnet, // Test chains Alfajores, BinanceSmartChainTestnet, Chiado, Holesky, MoonbaseAlpha, ScrollSepolia, From 1a9555defa921331f1bf83e3cd0c34d0bc207f72 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 21 Oct 2024 18:01:16 +0200 Subject: [PATCH 02/31] fix(indexer): constant cursor updates, is_contract_call fix --- .../main/chains/hyperlane-fuel/src/indexer.rs | 93 ++++++++----------- 1 file changed, 38 insertions(+), 55 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs index 5cb8323028..08372daea6 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -11,15 +11,13 @@ use fuels::{ BlockHeight, Bytes32, ContractId, }, }; -use futures::lock::Mutex; use hyperlane_core::{ ChainCommunicationError, ChainResult, ContractLocator, Indexed, LogMeta, H512, U256, }; use std::{ collections::HashMap, fmt::Debug, - ops::Deref, - sync::atomic::{AtomicBool, Ordering}, + ops::{Deref, RangeInclusive}, }; // TODO, clippy issues @@ -30,9 +28,6 @@ pub struct FuelIndexer { fuel_provider: FuelProvider, contract_address: Bech32ContractId, target_event_type: TransactionEventType, - block_cursor: Mutex>, - transaction_cursor: Mutex>, - cursors_initialized: AtomicBool, } /// IGP payment log has a data length of 48 bytes @@ -66,16 +61,13 @@ impl FuelIndexer { fuel_provider, contract_address, target_event_type, - block_cursor: Mutex::new(None), - transaction_cursor: Mutex::new(None), - cursors_initialized: AtomicBool::default(), } } /// Index logs depending on which transaction parser is passed as a parameter pub async fn index_logs_in_range( &self, - range: std::ops::RangeInclusive, + range: RangeInclusive, parser: fn( Vec<(Bytes32, TransactionResponse)>, ) -> Vec<(Bytes32, TransactionResponse, T, U256)>, @@ -84,12 +76,14 @@ impl FuelIndexer { T: Into>, T: PartialEq + Send + Sync + Debug + 'static, { - if !self.cursors_initialized.load(Ordering::Relaxed) { - self.initialize_cursors(&range).await; - } + let (block_cursor, transaction_cursor) = self.get_sync_cursors(&range).await?; - let (transaction_amount, transaction_map) = self.get_block_data(range).await.unwrap(); - let transaction_data = self.get_transaction_data(&transaction_map).await; + let (transaction_amount, transaction_map) = self + .get_block_data(range.clone(), block_cursor.clone()) + .await?; + let transaction_data = self + .get_transaction_data(&transaction_map, transaction_cursor.clone()) + .await?; let full_tx_data = parser(transaction_data); @@ -121,14 +115,13 @@ impl FuelIndexer { /// Check if a transaction is from a contract /// @note: Only works for checking script transactions - /// Assumes that the first input is the contract id #[allow(clippy::get_first)] fn is_transaction_from_contract( res: &TransactionResponse, contract: &Bech32ContractId, ) -> bool { if let TransactionType::Script(script_transaction) = &res.transaction { - if script_transaction.inputs().get(0).is_some_and(|input| { + if script_transaction.inputs().iter().any(|input| { input .contract_id() .is_some_and(|id| id == &ContractId::from(&contract.into())) @@ -142,10 +135,11 @@ impl FuelIndexer { async fn get_transaction_data( &self, transaction_map: &HashMap, - ) -> Vec<(Bytes32, TransactionResponse)> { + cursor: Option, + ) -> ChainResult> { let transaction_ids = transaction_map.keys().cloned().collect::>(); let req = PaginationRequest { - cursor: self.transaction_cursor.lock().await.clone(), + cursor, results: transaction_ids.len() as i32, direction: PageDirection::Forward, }; @@ -155,15 +149,7 @@ impl FuelIndexer { .provider() .get_transactions(req) .await - .map_err(ChainCommunicationError::from_other) - .unwrap(); - - *self.transaction_cursor.lock().await = transactions.cursor.clone(); - - assert!( - transactions.results.len() == transaction_ids.len(), - "Transaction data amount does not match transaction id amount" - ); + .map_err(ChainCommunicationError::from_other)?; let mut transaction_data = Vec::new(); for (tx_id, tx_data) in transactions.results.iter().zip(transaction_ids) { @@ -172,23 +158,26 @@ impl FuelIndexer { let transaction_matcher = self.get_transaction_matcher(); - transaction_data + let filtered_transactions = transaction_data .into_iter() .filter(|(_, tx_data)| { Self::is_transaction_from_contract(&tx_data, &self.contract_address) && transaction_matcher(&tx_data) }) - .collect::>() + .collect::>(); + + Ok(filtered_transactions) } async fn get_block_data( &self, - range: std::ops::RangeInclusive, + range: RangeInclusive, + cursor: Option, ) -> ChainResult<(i32, HashMap)> { - let result_amount = range.end() - range.start() + 1; + let result_amount: u32 = range.end() - range.start(); let req = PaginationRequest { - cursor: self.block_cursor.lock().await.clone(), - results: i32::try_from(result_amount).expect("Invalid range"), + cursor, + results: result_amount as i32, direction: PageDirection::Forward, }; @@ -198,7 +187,6 @@ impl FuelIndexer { .get_blocks(req) .await .map_err(ChainCommunicationError::from_other)?; - *self.block_cursor.lock().await = blocks.cursor.clone(); let mut transaction_map: HashMap = HashMap::new(); blocks.results.iter().for_each(|block| { @@ -220,18 +208,13 @@ impl FuelIndexer { Ok((transaction_amount, transaction_map)) } - async fn initialize_cursors(&self, range: &std::ops::RangeInclusive) { - let mut block_cursor_guard = self.block_cursor.lock().await; - let mut transaction_cursor_guard = self.transaction_cursor.lock().await; - assert!( - block_cursor_guard.is_none() && transaction_cursor_guard.is_none(), - "Cursors already initialized" - ); - + async fn get_sync_cursors( + &self, + range: &RangeInclusive, + ) -> ChainResult<(Option, Option)> { let range_start = range.start(); - if range.start() == &0 { - self.cursors_initialized.store(true, Ordering::Relaxed); - return; + if *range_start == 0 { + return Ok((None, None)); } let start_block = BlockHeight::from(*range_start); @@ -240,18 +223,18 @@ impl FuelIndexer { .provider() .block_by_height(start_block) .await - .expect("Failed to get block data") - .unwrap(); + .map_err(ChainCommunicationError::from_other) + .map(|block| block.unwrap())?; + let first_transaction = block_data.transactions.first().unwrap(); let hex_block = hex::encode(range_start.to_be_bytes()); let hex_tx = hex::encode(first_transaction.to_vec()); + let tx_cursor = Some(format!("{}#0x{}", hex_block, hex_tx)); let block_cursor = Some(range_start.to_string()); - *block_cursor_guard = block_cursor; - *transaction_cursor_guard = tx_cursor; - self.cursors_initialized.store(true, Ordering::Relaxed); + return Ok((block_cursor, tx_cursor)); } } @@ -306,10 +289,10 @@ impl FuelIndexer { let log_data_receipts = Self::filter_logdata_rec(receipts); - assert!( - log_data_receipts.len() == 1, - "IGP payment should have 1 log data receipt" - ); + // IGP payment should have 1 log data receipt + if log_data_receipts.len() != 1 { + return false; + } let log = log_data_receipts.get(0).unwrap(); match log { From a24439fa8e3b0a4342365af8f82eb578e2673e5f Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 21 Oct 2024 20:29:56 +0200 Subject: [PATCH 03/31] feat(indexer): make generic, reduce boilerplate --- .../main/chains/hyperlane-fuel/src/indexer.rs | 170 +++++++----------- .../hyperlane-fuel/src/interchain_gas.rs | 6 +- .../main/chains/hyperlane-fuel/src/mailbox.rs | 21 ++- .../hyperlane-fuel/src/merkle_tree_hook.rs | 13 +- 4 files changed, 90 insertions(+), 120 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs index 08372daea6..9a7f93e0eb 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -1,8 +1,20 @@ -use crate::{conversions::*, ConnectionConf, FuelProvider}; +use crate::{ + contracts::interchain_gas_paymaster::{ + GasPaymentEvent, InterchainGasPaymaster as FuelIgpContract, + }, + contracts::mailbox::{DispatchEvent, Mailbox as FuelMailboxContract}, + contracts::merkle_tree_hook::{MerkleTreeEvent, MerkleTreeHook as FuelMerkleTreeHookContract}, + conversions::*, + ConnectionConf, FuelProvider, +}; use fuels::{ accounts::wallet::WalletUnlocked, client::{PageDirection, PaginationRequest}, - tx::Receipt, + core::{ + codec::LogDecoder, + traits::{Parameterize, Tokenizable}, + }, + programs::calls::ContractDependency, types::{ bech32::Bech32ContractId, transaction::{Transaction, TransactionType}, @@ -23,48 +35,81 @@ use std::{ // TODO, clippy issues /// A wrapper around a fuel provider to get generic blockchain information. -#[derive(Debug)] pub struct FuelIndexer { fuel_provider: FuelProvider, contract_address: Bech32ContractId, - target_event_type: TransactionEventType, + event_checker: Box bool + Sync + Send>, +} + +// Implementing Debug for FuelIndexer +impl std::fmt::Debug for FuelIndexer { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FuelIndexer") + .field("fuel_provider", &self.fuel_provider) + .field("contract_address", &self.contract_address) + .field("event_checker", &"") + .finish() + } +} +/// Trait for getting decoders from different contracts depending on the event type +pub trait HasLogDecoder { + /// Get the log decoder for a specific contract + fn log_decoder(contract_address: Bech32ContractId, wallet: WalletUnlocked) -> LogDecoder; +} + +impl HasLogDecoder for DispatchEvent { + fn log_decoder(contract_address: Bech32ContractId, wallet: WalletUnlocked) -> LogDecoder { + FuelMailboxContract::new(contract_address, wallet).log_decoder() + } +} + +impl HasLogDecoder for GasPaymentEvent { + fn log_decoder(contract_address: Bech32ContractId, wallet: WalletUnlocked) -> LogDecoder { + FuelIgpContract::new(contract_address, wallet).log_decoder() + } } -/// IGP payment log has a data length of 48 bytes -const IGP_PAYMENT_LOG_LENGTH: usize = 48; -/// Dispatch is the only function call on the mailbox that has 2 log data receipts -const DISPATCH_LOG_DATA_REC_AMOUNT: usize = 2; - -/// Types of transaction logs that can be indexed -#[derive(Debug, Clone)] -pub enum TransactionEventType { - /// Event when a Mailbox dispatches a message - MailboxDispatch, - /// Event when and IGP payment is processed - IgpPayment, - /// Event when a MerkleTreeHook insertion is processed - MerkleTreeHookInsert, +impl HasLogDecoder for MerkleTreeEvent { + fn log_decoder(contract_address: Bech32ContractId, wallet: WalletUnlocked) -> LogDecoder { + FuelMerkleTreeHookContract::new(contract_address, wallet).log_decoder() + } } impl FuelIndexer { /// Create a new fuel indexer - pub async fn new( + /// -`T` is the type of event this indexer will be looking for + pub async fn new( conf: &ConnectionConf, locator: ContractLocator<'_>, wallet: WalletUnlocked, - target_event_type: TransactionEventType, - ) -> Self { + ) -> Self + where + T: Tokenizable + Parameterize + HasLogDecoder + 'static, + { let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; let contract_address = Bech32ContractId::from_h256(&locator.address); + let decoder = T::log_decoder(contract_address.clone(), wallet); + + let has_event_fn: Box bool + Send + Sync> = + Box::new(move |tx_data: &TransactionResponse| -> bool { + if let TxStatus::Success { receipts } = &tx_data.status { + if let Ok(decoded_logs) = decoder.decode_logs_with_type::(receipts) { + return !decoded_logs.is_empty(); + } + } + false + }); + Self { fuel_provider, contract_address, - target_event_type, + event_checker: has_event_fn, } } /// Index logs depending on which transaction parser is passed as a parameter + /// - `T` is the type of the indexed data pub async fn index_logs_in_range( &self, range: RangeInclusive, @@ -156,13 +201,11 @@ impl FuelIndexer { transaction_data.push((tx_data.clone(), tx_id.clone())); } - let transaction_matcher = self.get_transaction_matcher(); - let filtered_transactions = transaction_data .into_iter() .filter(|(_, tx_data)| { Self::is_transaction_from_contract(&tx_data, &self.contract_address) - && transaction_matcher(&tx_data) + && (self.event_checker)(tx_data) }) .collect::>(); @@ -237,80 +280,3 @@ impl FuelIndexer { return Ok((block_cursor, tx_cursor)); } } - -// Functions to make sure that the correct function is being filtered -impl FuelIndexer { - /// Get the correct function to validate a transaction depending on the indexer event target - fn get_transaction_matcher(&self) -> for<'a> fn(&'a TransactionResponse) -> bool { - match self.target_event_type { - TransactionEventType::MailboxDispatch => Self::is_dispatch_call, - TransactionEventType::IgpPayment => Self::is_igp_payment, - TransactionEventType::MerkleTreeHookInsert => Self::is_merkle_tree_insertion, - } - } - - /// Check if a transaction is a call to the dispatch function of the Mailbox contract - fn is_dispatch_call(res: &TransactionResponse) -> bool { - let receipts = match &res.status { - TxStatus::Success { receipts } => receipts, - _ => return false, - }; - - let log_data_receipts = Self::filter_logdata_rec(receipts); - - match log_data_receipts.len() { - DISPATCH_LOG_DATA_REC_AMOUNT => true, - _ => false, - } - } - - /// Check if a transaction is a call to the post dispatch function of the MerkleTreeHook contract - fn is_merkle_tree_insertion(res: &TransactionResponse) -> bool { - let receipts = match &res.status { - TxStatus::Success { receipts } => receipts, - _ => return false, - }; - - let log_data_receipts = Self::filter_logdata_rec(receipts); - - // Merkle tree insertion is the only function which has a single log data receipt - match log_data_receipts.len() { - 1 => true, - _ => false, - } - } - - /// Check if a transaction is a call to the pay_for_gas function of the IGP Hook contract - fn is_igp_payment(res: &TransactionResponse) -> bool { - let receipts = match &res.status { - TxStatus::Success { receipts } => receipts, - _ => return false, - }; - - let log_data_receipts = Self::filter_logdata_rec(receipts); - - // IGP payment should have 1 log data receipt - if log_data_receipts.len() != 1 { - return false; - } - let log = log_data_receipts.get(0).unwrap(); - - match log { - Receipt::LogData { data, .. } => data - .to_owned() - .is_some_and(|data| data.len() == IGP_PAYMENT_LOG_LENGTH), - _ => false, - } - } - - /// Retrieve only the logdata receipts - fn filter_logdata_rec(receipts: &Vec) -> Vec<&Receipt> { - receipts - .into_iter() - .filter(|rec| match rec { - Receipt::LogData { .. } => true, - _ => false, - }) - .collect::>() - } -} diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs index 1ffd2f26c6..d3252efbd8 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs @@ -1,8 +1,9 @@ +use crate::contracts::interchain_gas_paymaster::GasPaymentEvent; use crate::{ contracts::interchain_gas_paymaster::InterchainGasPaymaster as InterchainGasPaymasterContract, conversions::*, FuelProvider, }; -use crate::{ConnectionConf, FuelIndexer, TransactionEventType}; +use crate::{ConnectionConf, FuelIndexer}; use async_trait::async_trait; use fuels::accounts::wallet::WalletUnlocked; use fuels::tx::Receipt; @@ -83,8 +84,7 @@ impl FuelInterchainGasPaymasterIndexer { locator: ContractLocator<'_>, wallet: WalletUnlocked, ) -> ChainResult { - let indexer = - FuelIndexer::new(conf, locator, wallet, TransactionEventType::IgpPayment).await; + let indexer = FuelIndexer::new::(conf, locator, wallet).await; Ok(Self { indexer }) } diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 924488d110..f4e9ec7b6d 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -1,15 +1,16 @@ use crate::{ - contracts::mailbox::Mailbox as FuelMailboxContract, conversions::*, ConnectionConf, - FuelIndexer, FuelProvider, TransactionEventType, + contracts::mailbox::{DispatchEvent, EncodedMessage, Mailbox as FuelMailboxContract}, + conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, }; use async_trait::async_trait; use fuels::{ prelude::{Bech32ContractId, WalletUnlocked}, - programs::{calls::Execution, contract}, + programs::calls::Execution, tx::{Receipt, ScriptExecutionResult}, types::{ transaction::TxPolicies, transaction_response::TransactionResponse, tx_status::TxStatus, - Bytes, Bytes32, + Bits256, Bytes, Bytes32, }, }; use hyperlane_core::{ @@ -237,6 +238,15 @@ pub struct FuelMailboxIndexer { contract: FuelMailboxContract, } +fn mailbox_event() -> DispatchEvent { + DispatchEvent::new( + Bits256::zeroed(), + 0, + Bits256::zeroed(), + EncodedMessage::new(Bytes(vec![0])), + ) +} + impl FuelMailboxIndexer { /// Create a new FuelMailboxIndexer pub async fn new( @@ -248,9 +258,8 @@ impl FuelMailboxIndexer { Bech32ContractId::from_h256(&locator.address), wallet.clone(), ); - let indexer = - FuelIndexer::new(conf, locator, wallet, TransactionEventType::MailboxDispatch).await; + let indexer = FuelIndexer::new::(conf, locator, wallet).await; Ok(Self { indexer, contract }) } diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 25599c53a2..6fa4886814 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -1,8 +1,9 @@ use std::{num::NonZeroU64, ops::RangeInclusive}; use crate::{ - contracts::merkle_tree_hook::MerkleTreeHook as MerkleTreeHookContract, conversions::*, - ConnectionConf, FuelIndexer, FuelProvider, TransactionEventType, + contracts::merkle_tree_hook::{MerkleTreeEvent, MerkleTreeHook as MerkleTreeHookContract}, + conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, }; use async_trait::async_trait; use fuels::{ @@ -150,13 +151,7 @@ impl FuelMerkleTreeHookIndexer { Bech32ContractId::from_h256(&locator.address), wallet.clone(), ); - let indexer = FuelIndexer::new( - conf, - locator, - wallet, - TransactionEventType::MerkleTreeHookInsert, - ) - .await; + let indexer = FuelIndexer::new::(conf, locator, wallet).await; Ok(Self { indexer, contract }) } From 10aa2483cfb859eec08348b1fa94db4c94bb8ed2 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Thu, 24 Oct 2024 17:13:08 +0200 Subject: [PATCH 04/31] fix(fuel): small mailbox and ism tweaks --- .../hyperlane-fuel/abis/Mailbox.abi.json | 1000 ++++++++++++++--- .../src/interchain_security_module.rs | 4 + .../main/chains/hyperlane-fuel/src/mailbox.rs | 19 +- .../hyperlane-fuel/src/merkle_tree_hook.rs | 6 +- .../chains/hyperlane-fuel/src/provider.rs | 2 - 5 files changed, 848 insertions(+), 183 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json index ec2b5b7965..011fc1a0d6 100644 --- a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json @@ -423,7 +423,31 @@ { "name": "doc-comment", "arguments": [ - " Gets the default hook used for message processing." + " Gets the default hook used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ContractId] - Address implementing Hook interface." ] }, { @@ -445,6 +469,30 @@ " Gets the default ISM used for message verification." ] }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ContractId] - Address implementing ISM interface." + ] + }, { "name": "storage", "arguments": [ @@ -490,7 +538,31 @@ { "name": "doc-comment", "arguments": [ - " * `message_id` - The unique identifier of the message." + " * `message_id`: [b256] - The unique identifier of the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message has been processed." ] }, { @@ -560,133 +632,67 @@ { "name": "doc-comment", "arguments": [ - " * `destination_domain` - The domain of the destination chain." + " * `destination_domain`: [u32] - The domain of the destination chain." ] }, { "name": "doc-comment", "arguments": [ - " * `recipient` - Address of the recipient on the destination chain." + " * `recipient`: [b256] - Address of the recipient on the destination chain." ] }, { "name": "doc-comment", "arguments": [ - " * `message_body` - Raw bytes content of the message body." + " * `message_body`: [Bytes] - Raw bytes content of the message body." ] }, { - "name": "payable", - "arguments": [] - }, - { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read", - "write" + " * `metadata`: [Bytes] - Raw bytes content of the metadata." ] - } - ] - }, - { - "inputs": [ - { - "name": "owner", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - }, - { - "name": "default_ism", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - }, - { - "name": "default_hook", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, - { - "name": "required_hook", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - } - ], - "name": "initialize", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ { "name": "doc-comment", "arguments": [ - " Initializes the contract." + " * `hook`: [ContractId] - The hook contract Id." ] }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "write" + "" ] - } - ] - }, - { - "inputs": [], - "name": "latest_dispatched_id", - "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", - "attributes": [ + }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " ### Returns" ] - } - ] - }, - { - "inputs": [], - "name": "local_domain", - "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "attributes": [ + }, { "name": "doc-comment", "arguments": [ - " Returns the domain of the chain where the contract is deployed." + "" ] }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " * [b256] - The ID of the dispatched message." ] - } - ] - }, - { - "inputs": [], - "name": "nonce", - "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "attributes": [ + }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + "" ] - } - ] - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "process", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ { "name": "doc-comment", "arguments": [ - " Processes a message." + " ### Reverts" ] }, { @@ -698,27 +704,31 @@ { "name": "doc-comment", "arguments": [ - " ### Arguments" + " * If the message body is too large." ] }, { "name": "doc-comment", "arguments": [ - "" + " * If the contract is paused." ] }, { "name": "doc-comment", "arguments": [ - " * `metadata` - The metadata for ISM verification." + " * If reentrancy is detected." ] }, { "name": "doc-comment", "arguments": [ - " * `message` - The message as emitted by dispatch." + " * If any external call fails." ] }, + { + "name": "payable", + "arguments": [] + }, { "name": "storage", "arguments": [ @@ -731,33 +741,29 @@ { "inputs": [ { - "name": "destination_domain", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - }, - { - "name": "recipient_address", + "name": "owner", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { - "name": "message_body", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + "name": "default_ism", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + "name": "default_hook", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { - "name": "hook", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + "name": "required_hook", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ], - "name": "quote_dispatch", - "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", "arguments": [ - " Quotes the cost of dispatching a message to the destination domain and recipient." + " Initializes the contract." ] }, { @@ -781,81 +787,49 @@ { "name": "doc-comment", "arguments": [ - " * `destination_domain` - The domain of the destination chain." + " * `owner`: [b256] - The owner of the contract." ] }, { "name": "doc-comment", "arguments": [ - " * `recipient` - Address of the recipient on the destination chain." + " * `default_ism`: [b256] - The default ISM contract Id." ] }, { "name": "doc-comment", "arguments": [ - " * `message_body` - Raw bytes content of the message body." + " * `default_hook`: [b256] - The default hook contract Id." ] }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " * `required_hook`: [b256] - The required hook contract Id." ] - } - ] - }, - { - "inputs": [ - { - "name": "recipient", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "recipient_ism", - "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "attributes": [ + }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read", - "write" + "" ] - } - ] - }, - { - "inputs": [], - "name": "required_hook", - "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "attributes": [ + }, { "name": "doc-comment", "arguments": [ - " Gets the required hook used for message processing." + " ### Reverts" ] }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + "" ] - } - ] - }, - { - "inputs": [ - { - "name": "module", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "set_default_hook", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ + }, { "name": "doc-comment", "arguments": [ - " Sets the default hook used for message processing." + " * If the contract is already initialized." ] }, { @@ -867,19 +841,14 @@ ] }, { - "inputs": [ - { - "name": "module", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "set_default_ism", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "inputs": [], + "name": "latest_dispatched_id", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ { "name": "doc-comment", "arguments": [ - " Sets the default ISM used for message verification." + " Returns the ID of the last dispatched message." ] }, { @@ -891,7 +860,7 @@ { "name": "doc-comment", "arguments": [ - " ### Arguments" + " ### Returns" ] }, { @@ -903,23 +872,660 @@ { "name": "doc-comment", "arguments": [ - " * `module` - Address implementing ISM interface." + " * [b256] - The ID of the last dispatched message." ] }, { "name": "storage", "arguments": [ - "read", - "write" + "read" ] } ] }, { - "inputs": [ - { - "name": "module", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + "inputs": [], + "name": "local_domain", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the domain which is specified on contract initialization." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u32] - The domain of the contract." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "nonce", + "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the number of inserted leaves (i.e. messages) in the merkle tree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u32] - The number of leaves in the merkle tree." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "process", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Processes a message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata for ISM verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message as emitted by dispatch." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is paused." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If reentrancy is detected." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message has already been delivered." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message's protocol version is invalid." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message's origin is invalid." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message's verification fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If any external call fails." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "recipient_address", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "message_body", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "hook", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "quote_dispatch", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Quotes a price for dispatching a message" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `destination_domain`: [u32] - The domain of the destination chain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `recipient_address`: [b256] - Address of the recipient on the destination chain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message_body`: [Bytes] - Raw bytes content of the message body." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - Raw bytes content of the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `hook`: [ContractId] - The hook contract Id." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The price of the dispatch." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If any external call fails." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "recipient", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "recipient_ism", + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the ISM set by a recipient." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `recipient`: [ContractId] - The recipient's contract Id." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ContractId] - The ISM contract Id." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If recipient call fails." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "required_hook", + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the required hook used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ContractId] - Address implementing Hook interface." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "module", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "set_default_hook", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the required hook used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `module`: [ContractId] - Address implementing Hook interface." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the provided hook address is zero." + ] + }, + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "module", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "set_default_ism", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the default ISM used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `module`: [ContractId] - Address implementing ISM interface." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the provided ISM address is zero." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "module", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" } ], "name": "set_required_hook", @@ -928,7 +1534,61 @@ { "name": "doc-comment", "arguments": [ - " Sets the required hook used for message processing." + " Sets the required hook used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `module`: [ContractId] - Address implementing Hook interface." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the provided hook address is zero." ] }, { @@ -1119,7 +1779,7 @@ { "name": "LOCAL_DOMAIN", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 56248 + "offset": 55856 } ] } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs index 69f4940964..dc3577c443 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -59,6 +59,10 @@ impl HyperlaneChain for FuelInterchainSecurityModule { #[async_trait] impl InterchainSecurityModule for FuelInterchainSecurityModule { async fn module_type(&self) -> ChainResult { + if self.address() == H256::zero() { + return Ok(ModuleType::Null); + } + self.contract .methods() .module_type() diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 924488d110..a7554c0338 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -5,7 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ prelude::{Bech32ContractId, WalletUnlocked}, - programs::{calls::Execution, contract}, + programs::calls::Execution, tx::{Receipt, ScriptExecutionResult}, types::{ transaction::TxPolicies, transaction_response::TransactionResponse, tx_status::TxStatus, @@ -120,9 +120,11 @@ impl Mailbox for FuelMailbox { #[instrument(err, ret, skip(self))] #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue async fn recipient_ism(&self, recipient: H256) -> ChainResult { + let parsed_recipient = Bech32ContractId::from_h256(&recipient); self.contract .methods() - .recipient_ism(Bech32ContractId::from_h256(&recipient)) + .recipient_ism(parsed_recipient.clone()) + .with_contract_ids(&[parsed_recipient]) .simulate(Execution::StateReadOnly) .await .map(|r| r.value.into_h256()) @@ -197,6 +199,10 @@ impl Mailbox for FuelMailbox { message: &HyperlaneMessage, metadata: &[u8], ) -> ChainResult { + // The tolerance to go over the exact gas esimated is + // quite high due to the SDK reporting innacurate gas estimates + let tolerance = Some(1.0); + let call_res = self .contract .methods() @@ -204,15 +210,12 @@ impl Mailbox for FuelMailbox { Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) - .determine_missing_contracts(Some(3)) - .await - .map_err(ChainCommunicationError::from_other)? - .estimate_transaction_cost(None, None) + .estimate_transaction_cost(tolerance, None) .await .map_err(ChainCommunicationError::from_other)?; Ok(TxCostEstimate { - gas_limit: call_res.total_fee.into(), + gas_limit: call_res.gas_used.into(), gas_price: call_res.gas_price.into(), l2_gas_limit: None, }) @@ -354,7 +357,7 @@ impl SequenceAwareIndexer for FuelMailboxIndexer { .await .map(|r| r.value) .map_err(ChainCommunicationError::from_other) - .map(|sequence| (Some(sequence as u32), tip)) + .map(|sequence| (Some(sequence), tip)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 25599c53a2..90fa2633d2 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -15,9 +15,9 @@ use fuels::{ }; use hyperlane_core::{ accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint, - ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneIdentifier, - HyperlaneProvider, Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, - SequenceAwareIndexer, H256, U256, + ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneProvider, + Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, + U256, }; /// A reference to a AggregationIsm contract on some Fuel chain diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index e1614c2039..4e5a456a4a 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -1,5 +1,3 @@ -use std::io::Read; - use crate::{make_client, make_provider, ConnectionConf}; use async_trait::async_trait; use fuels::{ From 6bbcdaed3574b2334f4a710775b85ed90aa67a92 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 30 Oct 2024 08:57:36 +0100 Subject: [PATCH 05/31] fix(mailbox): gas estimation issues --- .../main/chains/hyperlane-fuel/src/mailbox.rs | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index a7554c0338..62f6e425d3 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -182,7 +182,15 @@ impl Mailbox for FuelMailbox { }) .any(|result| matches!(result, ScriptExecutionResult::Success)); - let tx_id = H512::from(call_res.tx_id.unwrap().into_h256()); + let tx_id = match call_res.tx_id { + Some(tx_id) => H512::from(tx_id.into_h256()), + None => { + return Err(ChainCommunicationError::from_other_str( + "Transaction ID not found", + )) + } + }; + Ok(TxOutcome { transaction_id: tx_id, executed: success, @@ -199,24 +207,25 @@ impl Mailbox for FuelMailbox { message: &HyperlaneMessage, metadata: &[u8], ) -> ChainResult { - // The tolerance to go over the exact gas esimated is - // quite high due to the SDK reporting innacurate gas estimates - let tolerance = Some(1.0); + let gas_price = self.provider.get_gas_price().await?; - let call_res = self + let simulate_call = self .contract .methods() .process( Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) - .estimate_transaction_cost(tolerance, None) + .determine_missing_contracts(Some(3)) + .await + .map_err(ChainCommunicationError::from_other)? + .simulate(Execution::Realistic) .await .map_err(ChainCommunicationError::from_other)?; Ok(TxCostEstimate { - gas_limit: call_res.gas_used.into(), - gas_price: call_res.gas_price.into(), + gas_limit: simulate_call.gas_used.into(), + gas_price: gas_price.into(), l2_gas_limit: None, }) } From 3b4ea46c00c37dce5c985265fb19c7dc58c8b76c Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 30 Oct 2024 09:02:08 +0100 Subject: [PATCH 06/31] feat(mailbox): add buffer to gas estimation --- rust/main/chains/hyperlane-fuel/src/mailbox.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 62f6e425d3..9365e55c4d 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -26,6 +26,7 @@ use std::{ }; use tracing::{instrument, warn}; +const GAS_ESTIMATE_MULTIPLIER: f64 = 1.3; /// A reference to a Mailbox contract on some Fuel chain pub struct FuelMailbox { contract: FuelMailboxContract, @@ -224,7 +225,7 @@ impl Mailbox for FuelMailbox { .map_err(ChainCommunicationError::from_other)?; Ok(TxCostEstimate { - gas_limit: simulate_call.gas_used.into(), + gas_limit: ((simulate_call.gas_used as f64 * GAS_ESTIMATE_MULTIPLIER) as u64).into(), gas_price: gas_price.into(), l2_gas_limit: None, }) From 1f310b48f9afb6ce1a9af30f90ab62e4b43cae20 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 1 Nov 2024 17:00:43 +0100 Subject: [PATCH 07/31] fix(warp-routes): add wr message indexer temp workaround --- rust/main/chains/hyperlane-fuel/src/indexer.rs | 1 + rust/main/chains/hyperlane-fuel/src/mailbox.rs | 11 +++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs index 08372daea6..4de06a31ed 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -260,6 +260,7 @@ impl FuelIndexer { match log_data_receipts.len() { DISPATCH_LOG_DATA_REC_AMOUNT => true, + 4 => true, _ => false, } } diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 9365e55c4d..af131cd0b4 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -18,12 +18,14 @@ use hyperlane_core::{ Indexed, Indexer, LogMeta, Mailbox, RawHyperlaneMessage, SequenceAwareIndexer, TxCostEstimate, TxOutcome, H256, H512, U256, }; + use std::{ collections::HashMap, fmt::{Debug, Formatter}, num::NonZeroU64, ops::RangeInclusive, }; + use tracing::{instrument, warn}; const GAS_ESTIMATE_MULTIPLIER: f64 = 1.3; @@ -166,7 +168,7 @@ impl Mailbox for FuelMailbox { Bytes(RawHyperlaneMessage::from(message)), ) .with_tx_policies(tx_policies) - .determine_missing_contracts(Some(3)) + .determine_missing_contracts(Some(10)) .await .map_err(ChainCommunicationError::from_other)? .call() @@ -217,7 +219,7 @@ impl Mailbox for FuelMailbox { Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) - .determine_missing_contracts(Some(3)) + .determine_missing_contracts(Some(10)) .await .map_err(ChainCommunicationError::from_other)? .simulate(Execution::Realistic) @@ -286,8 +288,9 @@ impl FuelMailboxIndexer { match rec { Receipt::LogData { .. } if rec - .data() - .is_some_and(|data| data.len() > NON_DISPATCH_LOG_LEN) => + .data() // TODO fix this + // .is_some_and(|data| data.len() > NON_DISPATCH_LOG_LEN) => + .is_some_and(|data| data.len() > 80) => { let data = rec.data().map(|data| data.to_owned()); From 795956a0b3a2efe17c420df3ea09f429a4055df8 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 1 Nov 2024 17:04:25 +0100 Subject: [PATCH 08/31] fix(warp-routes): with_variable_output_policy during process call --- rust/main/chains/hyperlane-fuel/src/mailbox.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index af131cd0b4..d48bf7564e 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -8,8 +8,8 @@ use fuels::{ programs::calls::Execution, tx::{Receipt, ScriptExecutionResult}, types::{ - transaction::TxPolicies, transaction_response::TransactionResponse, tx_status::TxStatus, - Bytes, Bytes32, + transaction::TxPolicies, transaction_builders::VariableOutputPolicy, + transaction_response::TransactionResponse, tx_status::TxStatus, Bytes, Bytes32, }, }; use hyperlane_core::{ @@ -167,6 +167,7 @@ impl Mailbox for FuelMailbox { Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) + .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum) .with_tx_policies(tx_policies) .determine_missing_contracts(Some(10)) .await @@ -219,6 +220,7 @@ impl Mailbox for FuelMailbox { Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) + .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum) .determine_missing_contracts(Some(10)) .await .map_err(ChainCommunicationError::from_other)? From 833f32c1548f4ff0e3cadf734b1b79714b2b2b94 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Tue, 5 Nov 2024 11:04:04 +0100 Subject: [PATCH 09/31] feat(fuel-integration): minor contract interface updates, bump fuels to latest --- rust/main/Cargo.lock | 100 ++++++++++-------- rust/main/Cargo.toml | 4 +- .../hyperlane-fuel/src/aggregation_ism.rs | 3 +- .../chains/hyperlane-fuel/src/routing_ism.rs | 6 +- .../hyperlane-fuel/src/trait_builder.rs | 1 + .../hyperlane-fuel/src/validator_announce.rs | 3 +- 6 files changed, 65 insertions(+), 52 deletions(-) diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index 01e6e305b7..f20451706f 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -3143,9 +3143,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "eventsource-client" -version = "0.12.2" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c80c6714d1a380314fcb11a22eeff022e1e1c9642f0bb54e15dc9cb29f37b29" +checksum = "43ddc25e1ad2cc0106d5e2d967397b4fb2068a66677ee9b0eea4600e5cfe8fb4" dependencies = [ "futures", "hyper", @@ -3343,9 +3343,9 @@ dependencies = [ [[package]] name = "fuel-asm" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b83807968cd62babe6cd70c94b76c86f302c8573da18b3c69135688eceecd" +checksum = "5f325971bf9047ec70004f80a989e03456316bc19cbef3ff3a39a38b192ab56e" dependencies = [ "bitflags 2.6.0", "fuel-types", @@ -3355,9 +3355,9 @@ dependencies = [ [[package]] name = "fuel-core-chain-config" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a4c5a71702426b8354bff2010131c0abb4a4f0b608cc7a6dfd72f9e785ba478" +checksum = "990db3029efd3766c4ae7c92a53c159ae66abf6f568ac6a3d58354f11400e6e2" dependencies = [ "anyhow", "bech32 0.9.1", @@ -3375,11 +3375,12 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5770dbda6220e641eb57ee204dd5914fa15170afe3009473f57cdf15e2339fd8" +checksum = "f09b3a35e82226d77b10653829beb508dc4bcf698fbdaa96610faf894e794444" dependencies = [ "anyhow", + "base64 0.22.1", "cynic", "derive_more 0.99.18", "eventsource-client", @@ -3399,22 +3400,25 @@ dependencies = [ [[package]] name = "fuel-core-metrics" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f671e9e813b81873ef07e1cfe8697ba3f9fd0f05313879ed0933446da4c1c14" +checksum = "94a1c3eb92040d95d27f7c658801bb5c04ad4aaf67de380cececbeed5aab6e61" dependencies = [ + "once_cell", "parking_lot 0.12.3", "pin-project-lite", "prometheus-client", "regex", + "strum 0.25.0", + "strum_macros 0.25.3", "tracing", ] [[package]] name = "fuel-core-poa" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b698e7c184ab4acbaabe7bad73fdc7dfc9ebfc3a6856b1d719a4fd4c1921873" +checksum = "2f6f78fa31dc56b9458e3ca9a7058b4bea381e16e49fcab0db49923be8a30f9c" dependencies = [ "anyhow", "async-trait", @@ -3431,24 +3435,25 @@ dependencies = [ [[package]] name = "fuel-core-services" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998a4f9d057bf3efe43be574bd200ef64c3318007fd04523ce6bd51cc7bb963c" +checksum = "8312b598da4b9a6503c9263c1c2a7ea58d34ab1f86e7f345490e12d309fb29bb" dependencies = [ "anyhow", "async-trait", "fuel-core-metrics", "futures", "parking_lot 0.12.3", + "pin-project-lite", "tokio", "tracing", ] [[package]] name = "fuel-core-storage" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1daa7422e48120b1623b53fe1a1152d11314f30fb290a73dc80f7e128c1f9014" +checksum = "bda9242ebc9e8ef3251b9eae85f4ce5cdb376348baa30925606f3ce602db7ec5" dependencies = [ "anyhow", "derive_more 0.99.18", @@ -3468,9 +3473,9 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.36.0" +version = "0.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aa1c54f09cc7c29a11ca1129f73105745f8374a192e3e24040c10822871d83f" +checksum = "6ee3a95b189bf729d21354a761862bb481298cbd883550adc3fef1bc7beb0b67" dependencies = [ "anyhow", "bs58 0.5.1", @@ -3486,9 +3491,9 @@ dependencies = [ [[package]] name = "fuel-crypto" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a4ca62d0a8a361b66a6eab3456285883d0aa92c407e249fc76f195c332fbb2" +checksum = "65e318850ca64890ff123a99b6b866954ef49da94ab9bc6827cf6ee045568585" dependencies = [ "coins-bip32 0.8.7", "coins-bip39 0.8.7", @@ -3507,9 +3512,9 @@ dependencies = [ [[package]] name = "fuel-derive" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ca99d9c264fec231a01e55bbdb6adb3080266dc44c4cc88de870b089ee2a015" +checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ "proc-macro2 1.0.86", "quote 1.0.37", @@ -3519,9 +3524,9 @@ dependencies = [ [[package]] name = "fuel-merkle" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02f3c08f22f7c24170a4ac255e7dfe52d52ae2e85c4a8e26ed6df4f1bd380210" +checksum = "c79eca6a452311c70978a5df796c0f99f27e474b69719e0db4c1d82e68800d07" dependencies = [ "derive_more 0.99.18", "digest 0.10.7", @@ -3534,15 +3539,15 @@ dependencies = [ [[package]] name = "fuel-storage" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d676ea5d926bf90c8ea442e5f6fc23c0e86c2e4d663f303842b4afe5b7928084" +checksum = "2d0c46b5d76b3e11197bd31e036cd8b1cb46c4d822cacc48836638080c6d2b76" [[package]] name = "fuel-tx" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86158d08fe2a936ac765a1e2cb9bf60be704203b3085882e7cc6cd4c48de38ef" +checksum = "6723bb8710ba2b70516ac94d34459593225870c937670fb3afaf82e0354667ac" dependencies = [ "bitflags 2.6.0", "derivative", @@ -3556,16 +3561,15 @@ dependencies = [ "postcard", "rand 0.8.5", "serde", - "serde_json", "strum 0.24.1", "strum_macros 0.24.3", ] [[package]] name = "fuel-types" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42b4430c6a20669fffd8f2c17d2be6809a356f623243a78b5eedf8ba7897c036" +checksum = "982265415a99b5bd6277bc24194a233bb2e18764df11c937b3dbb11a02c9e545" dependencies = [ "fuel-derive", "hex 0.4.3", @@ -3575,9 +3579,9 @@ dependencies = [ [[package]] name = "fuel-vm" -version = "0.57.1" +version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1b04a4e971d58b3662ff8b84b3176094e25f4b372728a13ea903fdf79c7e426" +checksum = "54b5362d7d072c72eec20581f67fc5400090c356a7f3ae77c79880b3b177b667" dependencies = [ "anyhow", "async-trait", @@ -3609,9 +3613,9 @@ dependencies = [ [[package]] name = "fuels" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaf7ca0443308f4c3d3e9dd7ed67cb18369ae63d208302056d6d5f3a09efb031" +checksum = "6ed08053e72bdb285d5a167c27a7a0d10f1dc4e27d1e6e5296dd2a67813bd13f" dependencies = [ "fuel-core-client", "fuel-crypto", @@ -3625,12 +3629,13 @@ dependencies = [ [[package]] name = "fuels-accounts" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ea69afa418ba67b9572a5b4cb612b80ee2113c9f755e93acf7adc9fc1454d1" +checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" dependencies = [ "async-trait", "chrono", + "cynic", "elliptic-curve 0.13.8", "eth-keystore", "fuel-core-client", @@ -3650,9 +3655,9 @@ dependencies = [ [[package]] name = "fuels-code-gen" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8d1949debe40c9eb731a93b22a50da560007d85f6f7983679d217c01b9dc867" +checksum = "f857b7ff658400506ca6be57bb84fedda44b566e78f5f0a8d0782242f41615c0" dependencies = [ "Inflector", "fuel-abi-types", @@ -3666,9 +3671,9 @@ dependencies = [ [[package]] name = "fuels-core" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e720a87a7c99fcc5477cbb251738406de752a10eb237e15c79c1d99b64f4679f" +checksum = "baccbdd81e624f57950dcb136b32b853c520dd954badf26b9f58de33f3d71c7e" dependencies = [ "async-trait", "bech32 0.9.1", @@ -3688,15 +3693,16 @@ dependencies = [ "postcard", "serde", "serde_json", + "sha2 0.10.8", "thiserror", "uint 0.9.5", ] [[package]] name = "fuels-macros" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7b391259fceb75331bcbde2878cd9765b579e9167abd818641205b4c96b9a" +checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" dependencies = [ "fuels-code-gen", "itertools 0.12.1", @@ -3707,9 +3713,9 @@ dependencies = [ [[package]] name = "fuels-programs" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf719a68184ad4999c24dd53cf68bdd247d02fe16a9d67ccba177c8e44771b9" +checksum = "32675ed1c08edd28ddb648dfae0c60a1946d4368a69ddfa6434f2316e33f0520" dependencies = [ "async-trait", "fuel-abi-types", @@ -3726,9 +3732,9 @@ dependencies = [ [[package]] name = "fuels-test-helpers" -version = "0.66.5" +version = "0.66.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a615a59644d3cfce8dc1089db0764b4cca2bcea42b2a08eca826e2b8f892936" +checksum = "02176c0fb1bf8cf58b8a9e5372efb650324740abcd4847b45bd0b041a0f133a2" dependencies = [ "fuel-core-chain-config", "fuel-core-client", diff --git a/rust/main/Cargo.toml b/rust/main/Cargo.toml index 09036e9c96..59a051b7ef 100644 --- a/rust/main/Cargo.toml +++ b/rust/main/Cargo.toml @@ -63,8 +63,8 @@ dhat = "0.3.3" ed25519-dalek = "~1.0" eyre = "=0.6.8" fixed-hash = "0.8.0" -fuels = "0.66.5" -fuels-code-gen = "0.66.5" +fuels = { version = "0.66.9", features = ["coin-cache"] } +fuels-code-gen = "0.66.9" futures = "0.3" futures-util = "0.3" generic-array = { version = "0.14", features = ["serde", "more_lengths"] } diff --git a/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs index 33b4ef0c2e..e83acc4241 100644 --- a/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs @@ -5,6 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ accounts::wallet::WalletUnlocked, + programs::calls::Execution, types::{bech32::Bech32ContractId, Bytes}, }; use hyperlane_core::{ @@ -65,7 +66,7 @@ impl AggregationIsm for FuelAggregationIsm { self.contract .methods() .modules_and_threshold(Bytes(message.to_vec())) - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| { diff --git a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs index 5ce81747f1..4b63553e24 100644 --- a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs @@ -5,6 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ accounts::wallet::WalletUnlocked, + programs::calls::Execution, types::{bech32::Bech32ContractId, Bytes}, }; use hyperlane_core::{ @@ -63,7 +64,10 @@ impl RoutingIsm for FuelRoutingIsm { self.contract .methods() .route(Bytes(message.to_vec())) - .call() + .determine_missing_contracts(Some(10)) + .await + .map_err(ChainCommunicationError::from_other)? + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| res.value.into_h256()) diff --git a/rust/main/chains/hyperlane-fuel/src/trait_builder.rs b/rust/main/chains/hyperlane-fuel/src/trait_builder.rs index 0a6965028b..16e9a49e93 100644 --- a/rust/main/chains/hyperlane-fuel/src/trait_builder.rs +++ b/rust/main/chains/hyperlane-fuel/src/trait_builder.rs @@ -7,6 +7,7 @@ use url::Url; pub struct ConnectionConf { /// Fully qualified string to connect to pub url: Url, + /// Config for batching messages pub operation_batch: OperationBatchConfig, } diff --git a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs index 3c8d53c931..470a45c702 100644 --- a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs +++ b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs @@ -5,6 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ prelude::WalletUnlocked, + programs::calls::Execution, tx::{Receipt, ScriptExecutionResult}, types::{bech32::Bech32ContractId, Address, Bits256, Bytes}, }; @@ -70,7 +71,7 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { .get_announced_storage_locations( validators.iter().map(|v| Bits256::from_h256(v)).collect(), ) - .call() + .simulate(Execution::StateReadOnly) .await .map(|res| res.value) .map_err(ChainCommunicationError::from_other) From fe93d234cf01a1f05404c72761b8602b0468f8fb Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 11 Nov 2024 10:44:32 +0100 Subject: [PATCH 10/31] feat(fuel-integration): fuel contract interface updates from the demos --- rust/main/Cargo.lock | 1 + rust/main/chains/hyperlane-fuel/Cargo.toml | 1 + .../abis/MerkleTreeHook.abi.json | 506 +++++++- .../hyperlane-fuel/abis/MultisigISM.abi.json | 1105 ++++++++++++----- .../main/chains/hyperlane-fuel/src/indexer.rs | 31 +- .../src/interchain_security_module.rs | 16 +- .../main/chains/hyperlane-fuel/src/mailbox.rs | 1 + .../hyperlane-fuel/src/merkle_tree_hook.rs | 72 +- .../chains/hyperlane-fuel/src/multisig_ism.rs | 3 +- .../hyperlane-fuel/src/validator_announce.rs | 25 +- 10 files changed, 1330 insertions(+), 431 deletions(-) diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index f20451706f..b86f4928ca 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -4618,6 +4618,7 @@ dependencies = [ "hyperlane-core", "serde", "thiserror", + "tokio", "tracing", "tracing-futures", "url", diff --git a/rust/main/chains/hyperlane-fuel/Cargo.toml b/rust/main/chains/hyperlane-fuel/Cargo.toml index 3b8f795983..da65af6686 100644 --- a/rust/main/chains/hyperlane-fuel/Cargo.toml +++ b/rust/main/chains/hyperlane-fuel/Cargo.toml @@ -18,6 +18,7 @@ tracing-futures.workspace = true tracing.workspace = true hex.workspace = true url.workspace = true +tokio.workspace = true hyperlane-core = { path = "../../hyperlane-core", features = ["async"] } diff --git a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json index 57d7f34917..a730cae86f 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json @@ -10,6 +10,11 @@ { "type": "(b256, u32)", "concreteTypeId": "ca65b5ac32a1d2b9c2c913a704974f17a67f9ed81cdd78007c6584eb8feb5e95", + "metadataTypeId": 1 + }, + { + "type": "(u32, u32)", + "concreteTypeId": "c01e801cd76e1f67f52a84fd90af41cca92724d7aa0326270953a5fb5e9f5af1", "metadataTypeId": 0 }, { @@ -23,11 +28,6 @@ { "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5", - "metadataTypeId": 2 - }, - { - "type": "enum interfaces::merkle_tree_hook::MerkleTreeEvent", - "concreteTypeId": "13d1ea5564f062bef216aab38d2d55b58fb43f440a67b87a5f44af5c09faabcd", "metadataTypeId": 3 }, { @@ -40,20 +40,25 @@ "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb", "metadataTypeId": 5 }, + { + "type": "struct interfaces::merkle_tree_hook::InsertedIntoTreeEvent", + "concreteTypeId": "3effa20b4d80bbc5778de2fd83fda27778f7cda3c122fe2120a4d3298509abcc", + "metadataTypeId": 7 + }, { "type": "struct merkle::MerkleTree", "concreteTypeId": "4f367a560e7594cc203b566f49d1b5f9a43fb5e5c4172cef5eb32b9dc5a0d0df", - "metadataTypeId": 7 + "metadataTypeId": 8 }, { "type": "struct std::bytes::Bytes", "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 8 + "metadataTypeId": 9 }, { "type": "struct std::contract_id::ContractId", "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 10 + "metadataTypeId": 11 }, { "type": "u32", @@ -68,6 +73,20 @@ { "type": "(_, _)", "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "__tuple_element", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "(_, _)", + "metadataTypeId": 1, "components": [ { "name": "__tuple_element", @@ -81,7 +100,7 @@ }, { "type": "[_; 32]", - "metadataTypeId": 1, + "metadataTypeId": 2, "components": [ { "name": "__array_element", @@ -91,7 +110,7 @@ }, { "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", - "metadataTypeId": 2, + "metadataTypeId": 3, "components": [ { "name": "MessageNotDispatching", @@ -111,16 +130,6 @@ } ] }, - { - "type": "enum interfaces::merkle_tree_hook::MerkleTreeEvent", - "metadataTypeId": 3, - "components": [ - { - "name": "InsertedIntoTree", - "typeId": 0 - } - ] - }, { "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", "metadataTypeId": 4, @@ -186,12 +195,26 @@ "metadataTypeId": 6 }, { - "type": "struct merkle::MerkleTree", + "type": "struct interfaces::merkle_tree_hook::InsertedIntoTreeEvent", "metadataTypeId": 7, + "components": [ + { + "name": "message_id", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "index", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "struct merkle::MerkleTree", + "metadataTypeId": 8, "components": [ { "name": "branch", - "typeId": 1 + "typeId": 2 }, { "name": "count", @@ -201,11 +224,11 @@ }, { "type": "struct std::bytes::Bytes", - "metadataTypeId": 8, + "metadataTypeId": 9, "components": [ { "name": "buf", - "typeId": 9 + "typeId": 10 }, { "name": "len", @@ -215,7 +238,7 @@ }, { "type": "struct std::bytes::RawBytes", - "metadataTypeId": 9, + "metadataTypeId": 10, "components": [ { "name": "ptr", @@ -229,7 +252,7 @@ }, { "type": "struct std::contract_id::ContractId", - "metadataTypeId": 10, + "metadataTypeId": 11, "components": [ { "name": "bits", @@ -244,6 +267,91 @@ "name": "count", "output": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the count from the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u32] - The count from the MerkleTree." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "count_and_block", + "output": "c01e801cd76e1f67f52a84fd90af41cca92724d7aa0326270953a5fb5e9f5af1", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the stored count of the MerkleTree library." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " And the current block number." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " Used since we cannot query point in time data." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [(u32, u32)] - The count and the current block number." + ] + }, { "name": "storage", "arguments": [ @@ -262,6 +370,60 @@ "name": "initialize", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Initializes the MerkleTreeHook contract with the given mailbox contract ID." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `mailbox`: [ContractId] - The contract ID of the mailbox contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is already initialized." + ] + }, { "name": "storage", "arguments": [ @@ -288,6 +450,36 @@ "name": "root", "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the root from the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [b256] - The root from the MerkleTree." + ] + }, { "name": "storage", "arguments": [ @@ -301,6 +493,42 @@ "name": "tree", "output": "4f367a560e7594cc203b566f49d1b5f9a43fb5e5c4172cef5eb32b9dc5a0d0df", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the latest checkpoint from the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [b256] - The root from the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u32] - The count from the MerkleTree." + ] + }, { "name": "storage", "arguments": [ @@ -314,6 +542,36 @@ "name": "hook_type", "output": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of hook" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [PostDispatchHookType] - The type of the hook." + ] + }, { "name": "storage", "arguments": [ @@ -336,6 +594,84 @@ "name": "post_dispatch", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Post action after a message is dispatched via the Mailbox" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " For the MerkleTreeHook, this function inserts the message ID into the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message ID is not the latest dispatched ID." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If there was assets sent with the function call." + ] + }, { "name": "payable", "arguments": [] @@ -363,6 +699,66 @@ "name": "quote_dispatch", "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Compute the payment required by the postDispatch call" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The payment required for the postDispatch call." + ] + }, { "name": "storage", "arguments": [ @@ -381,6 +777,60 @@ "name": "supports_metadata", "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns whether the hook supports metadata" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be checked." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - Whether the hook supports the metadata." + ] + }, { "name": "storage", "arguments": [ @@ -400,8 +850,8 @@ "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb" }, { - "logId": "1428180209339753150", - "concreteTypeId": "13d1ea5564f062bef216aab38d2d55b58fb43f440a67b87a5f44af5c09faabcd" + "logId": "4539525118841371589", + "concreteTypeId": "3effa20b4d80bbc5778de2fd83fda27778f7cda3c122fe2120a4d3298509abcc" } ], "messagesTypes": [], diff --git a/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json index 2079ef84e3..9859af060e 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json @@ -1,346 +1,761 @@ { - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "(struct std::vec::Vec, u8)", - "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", - "metadataTypeId": 0 - }, - { - "type": "bool", - "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" - }, - { - "type": "enum MessageIdMultisigError", - "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e", - "metadataTypeId": 2 - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "metadataTypeId": 3 - }, - { - "type": "struct std::bytes::Bytes", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 6 - }, - { - "type": "struct std::vm::evm::evm_address::EvmAddress", - "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", - "metadataTypeId": 10 - }, - { - "type": "u32", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - }, - { - "type": "u8", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "metadataTypes": [ - { - "type": "(_, _)", - "metadataTypeId": 0, - "components": [ - { - "name": "__tuple_element", - "typeId": 9, - "typeArguments": [ - { - "name": "", - "typeId": 10 - } - ] - }, - { - "name": "__tuple_element", - "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ] - }, - { - "type": "b256", - "metadataTypeId": 1 - }, - { - "type": "enum MessageIdMultisigError", - "metadataTypeId": 2, - "components": [ - { - "name": "NoMultisigThreshold", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NoValidatorMatch", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "FailedToRecoverSigner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "FailedToRecoverSignature", - "typeId": 6 - } - ] - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "metadataTypeId": 3, - "components": [ - { - "name": "UNUSED", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "ROUTING", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "AGGREGATION", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "LEGACY_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MERKLE_ROOT_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MESSAGE_ID_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NULL", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "CCIP_READ", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 4 - }, - { - "type": "raw untyped ptr", - "metadataTypeId": 5 - }, - { - "type": "struct std::bytes::Bytes", - "metadataTypeId": 6, - "components": [ - { - "name": "buf", - "typeId": 7 - }, - { - "name": "len", - "typeId": 11 - } - ] - }, - { - "type": "struct std::bytes::RawBytes", - "metadataTypeId": 7, - "components": [ - { - "name": "ptr", - "typeId": 5 - }, - { - "name": "cap", - "typeId": 11 - } - ] - }, - { - "type": "struct std::vec::RawVec", - "metadataTypeId": 8, - "components": [ - { - "name": "ptr", - "typeId": 5 - }, - { - "name": "cap", - "typeId": 11 - } - ], - "typeParameters": [ - 4 - ] - }, - { - "type": "struct std::vec::Vec", - "metadataTypeId": 9, - "components": [ - { - "name": "buf", - "typeId": 8, - "typeArguments": [ - { - "name": "", - "typeId": 4 - } - ] - }, - { - "name": "len", - "typeId": 11 - } - ], - "typeParameters": [ - 4 - ] - }, - { - "type": "struct std::vm::evm::evm_address::EvmAddress", - "metadataTypeId": 10, - "components": [ - { - "name": "bits", - "typeId": 1 - } - ] - }, - { - "type": "u64", - "metadataTypeId": 11 - } - ], - "functions": [ - { - "inputs": [], - "name": "module_type", - "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "attributes": null - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "verify", - "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "digest", - "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "attributes": null - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "index", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - } - ], - "name": "signature_at", - "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "attributes": null - }, - { - "inputs": [ - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "validators_and_threshold", - "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "validator", - "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" - } - ], - "name": "enroll_validator", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "threshold", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "name": "set_threshold", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "12857203263801679462", - "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e" - } - ], - "messagesTypes": [], - "configurables": [] - } \ No newline at end of file + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum MerkleRootMultisigError", + "concreteTypeId": "838f554c0502325db7a2eb625a0eb694105f5366eb11999093426c18433a2969", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 3 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 6 + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 10 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 10 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum MerkleRootMultisigError", + "metadataTypeId": 2, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InvalidMerkleIndexMetadata", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 6 + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 3, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 4 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 5 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 6, + "components": [ + { + "name": "buf", + "typeId": 7 + }, + { + "name": "len", + "typeId": 11 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 7, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 8, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 9, + "components": [ + { + "name": "buf", + "typeId": 8, + "typeArguments": [ + { + "name": "", + "typeId": 4 + } + ] + }, + { + "name": "len", + "typeId": 11 + } + ], + "typeParameters": [ + 4 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 11 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ModuleType] - The type of security model." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Verifies the message using the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be verified." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the threshold is not set or is less than 0." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the signature recovery fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the signer recovery fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If no validator matches the signer." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "digest", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the digest to be used for signature verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - ABI encoded module metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - Formatted Hyperlane message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Bytes] - The digest to be signed by validators." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message index and signed index do not match." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If data passed in is invalid." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "index", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "signature_at", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the signature at a given index from the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - ABI encoded module metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `index`: [u32] - The index of the signature to be retrieved." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Bytes] - Packed encoding of signature (65 bytes)." + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "validators_and_threshold", + "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the validators and threshold for the Multisig ISM for the given message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of validators that are set to approve the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u8] - The threshold of approval for the Multisig ISM." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + } + ], + "name": "enroll_validator", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Enrolls a validator to the Multisig ISM." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validator`: [EvmAddress] - The address of the validator to be enrolled." + ] + }, + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "set_threshold", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the threshold for the Multisig ISM." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `threshold`: [u8] - The threshold of approval for the Multisig ISM." + ] + }, + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "9479889525628088925", + "concreteTypeId": "838f554c0502325db7a2eb625a0eb694105f5366eb11999093426c18433a2969" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs index 4de06a31ed..cc762a0548 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -218,15 +218,29 @@ impl FuelIndexer { } let start_block = BlockHeight::from(*range_start); - let block_data = self + let block_data = match self .fuel_provider .provider() .block_by_height(start_block) .await - .map_err(ChainCommunicationError::from_other) - .map(|block| block.unwrap())?; + .map_err(ChainCommunicationError::from_other)? + { + Some(block) => block, + None => { + return Err(ChainCommunicationError::from_other_str( + "Block not found while building cursors", + )) + } + }; - let first_transaction = block_data.transactions.first().unwrap(); + let first_transaction = match block_data.transactions.first() { + Some(tx) => tx, + None => { + return Err(ChainCommunicationError::from_other_str( + "Failed to get first transaction in block while building cursors", + )) + } + }; let hex_block = hex::encode(range_start.to_be_bytes()); let hex_tx = hex::encode(first_transaction.to_vec()); @@ -258,8 +272,10 @@ impl FuelIndexer { let log_data_receipts = Self::filter_logdata_rec(receipts); + // TODO fix this, this is a hack match log_data_receipts.len() { DISPATCH_LOG_DATA_REC_AMOUNT => true, + 3 => true, // Dispatch with igp hook, this system is bullshit 4 => true, _ => false, } @@ -275,9 +291,10 @@ impl FuelIndexer { let log_data_receipts = Self::filter_logdata_rec(receipts); // Merkle tree insertion is the only function which has a single log data receipt - match log_data_receipts.len() { - 1 => true, - _ => false, + // TODO this is a hack, fix this + match log_data_receipts.len() >= 1 { + true => true, + false => false, } } diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs index dc3577c443..b30c00527f 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -4,12 +4,14 @@ use crate::{ }; use async_trait::async_trait; use fuels::{ - accounts::wallet::WalletUnlocked, programs::calls::Execution, types::bech32::Bech32ContractId, + accounts::wallet::WalletUnlocked, + programs::calls::Execution, + types::{bech32::Bech32ContractId, Bytes}, }; use hyperlane_core::{ ChainCommunicationError, ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, InterchainSecurityModule, ModuleType, - H256, U256, + RawHyperlaneMessage, H256, U256, }; /// A reference to a AggregationIsm contract on some Fuel chain @@ -66,7 +68,7 @@ impl InterchainSecurityModule for FuelInterchainSecurityModule { self.contract .methods() .module_type() - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| IsmType(res.value).into()) @@ -79,7 +81,13 @@ impl InterchainSecurityModule for FuelInterchainSecurityModule { ) -> ChainResult> { self.contract .methods() - .module_type() + .verify( + Bytes(metadata.to_vec()), + Bytes(RawHyperlaneMessage::from(message)), + ) + .determine_missing_contracts(Some(10)) + .await + .map_err(ChainCommunicationError::from_other)? .simulate(Execution::Realistic) .await .map_err(ChainCommunicationError::from_other) diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index d48bf7564e..bc8e58a981 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -271,6 +271,7 @@ impl FuelMailboxIndexer { Ok(Self { indexer, contract }) } + /// Parse the logs from the mailbox contract pub fn mailbox_parser( transactions: Vec<(Bytes32, TransactionResponse)>, ) -> Vec<(Bytes32, TransactionResponse, HyperlaneMessage, U256)> { diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 90fa2633d2..e7a1a492af 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -1,5 +1,3 @@ -use std::{num::NonZeroU64, ops::RangeInclusive}; - use crate::{ contracts::merkle_tree_hook::MerkleTreeHook as MerkleTreeHookContract, conversions::*, ConnectionConf, FuelIndexer, FuelProvider, TransactionEventType, @@ -7,6 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ accounts::wallet::WalletUnlocked, + programs::calls::Execution, tx::Receipt, types::{ bech32::Bech32ContractId, transaction_response::TransactionResponse, tx_status::TxStatus, @@ -19,6 +18,7 @@ use hyperlane_core::{ Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, U256, }; +use std::{num::NonZeroU64, ops::RangeInclusive}; /// A reference to a AggregationIsm contract on some Fuel chain #[derive(Debug)] @@ -46,6 +46,16 @@ impl FuelMerkleTreeHook { provider: fuel_provider, }) } + + /// Simulate lag on call + /// Since we have no way of querying point in time data, we can only simulate lag + /// by sleeping for the lag amount of time. As lag is usually 1 based on the re-org + /// we would normally sleep for 1 second. + async fn simulate_lag(&self, lag: Option) { + if let Some(lag) = lag { + tokio::time::sleep(std::time::Duration::from_secs(lag.get())).await; + } + } } impl HyperlaneContract for FuelMerkleTreeHook { @@ -67,15 +77,12 @@ impl HyperlaneChain for FuelMerkleTreeHook { #[async_trait] impl MerkleTreeHook for FuelMerkleTreeHook { async fn tree(&self, lag: Option) -> ChainResult { - assert!( - lag.is_none(), - "Fuel does not support querying point-in-time" - ); + self.simulate_lag(lag).await; self.contract .methods() .tree() - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| { @@ -88,30 +95,24 @@ impl MerkleTreeHook for FuelMerkleTreeHook { } async fn count(&self, lag: Option) -> ChainResult { - assert!( - lag.is_none(), - "Fuel does not support querying point-in-time" - ); + self.simulate_lag(lag).await; self.contract .methods() .count() - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| res.value) } async fn latest_checkpoint(&self, lag: Option) -> ChainResult { - assert!( - lag.is_none(), - "Fuel does not support querying point-in-time" - ); + self.simulate_lag(lag).await; self.contract .methods() .latest_checkpoint() - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| { @@ -172,30 +173,26 @@ impl FuelMerkleTreeHookIndexer { TxStatus::Success { receipts } => receipts, _ => return None, }; - let (log_index, receipt_log_data) = receipts .into_iter() .enumerate() .filter_map(|(log_index, rec)| match rec { - Receipt::LogData { .. } if rec.data().is_some() => { - let data = rec.data().map(|data| data.to_owned()); + Receipt::LogData { .. } + if rec.data().is_some_and(|data| data.len() == 36) => + { + let data = rec.data().map(|data| data.to_owned()).unwrap(); - match data { - Some(data) => Some((U256::from(log_index), data)), - _ => None, - } + Some((U256::from(log_index), data)) } _ => None, }) - .next()?; // Each merkle tree hook post dispatch call should have only one logdata receipt + .next()?; // Each merkle tree hook post dispatch call should have only one isert receipt if !receipt_log_data.is_empty() { // The log is strucutred to have a message id first and the leaf index following it let (id, index) = receipt_log_data.split_at(MESSAGE_ID_LEN); - let message_id = - H256::from(<[u8; 32]>::try_from(id).expect("slice with incorrect length")); - let leaf_index = - u32::from_be_bytes(index.try_into().expect("slice with incorrect length")); + let message_id = H256::from(<[u8; 32]>::try_from(id).unwrap()); + let leaf_index = u32::from_be_bytes(index.try_into().unwrap()); let insertion = MerkleTreeInsertion::new(leaf_index, message_id); @@ -229,13 +226,22 @@ impl Indexer for FuelMerkleTreeHookIndexer { #[async_trait] impl SequenceAwareIndexer for FuelMerkleTreeHookIndexer { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { - let tip = self.get_finalized_block_number().await?; + // TODO make sure the block is finalized, somehow + // Could make a function in sway that checks the stored last count update, + // if the last count update is the current block, then we return count-1 and block-1 + // else we return count and block + // this would mess up if there are mutiple count updates per block + // in that case we can store the amount of updates per block as well + self.contract .methods() - .count() - .call() + .count_and_block() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) - .map(|res| (Some(res.value), tip)) + .map(|res| { + let (count, tip) = res.value; + (Some(count), tip) + }) } } diff --git a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs index f8d95593bd..eb8a615662 100644 --- a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs @@ -5,6 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ accounts::wallet::WalletUnlocked, + programs::calls::Execution, types::{bech32::Bech32ContractId, Bytes}, }; use hyperlane_core::{ @@ -66,7 +67,7 @@ impl MultisigIsm for FuelMultisigIsm { self.contract .methods() .validators_and_threshold(Bytes(message.to_vec())) - .call() + .simulate(Execution::StateReadOnly) .await .map_err(ChainCommunicationError::from_other) .map(|res| (res.value.0.into_h256_vec(), res.value.1)) diff --git a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs index 470a45c702..340103e5b4 100644 --- a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs +++ b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs @@ -111,10 +111,7 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { } async fn announce_tokens_needed(&self, announcement: SignedType) -> Option { - let tolerance = Some(0.0); - let block_horizon = Some(1); - - let cost_estimation = self + let simulate_call = self .contract .methods() .announce( @@ -122,19 +119,21 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { announcement.value.storage_location, Bytes(announcement.signature.to_vec()), ) - .estimate_transaction_cost(tolerance, block_horizon) + .simulate(Execution::Realistic) .await; - let signer = Address::from(self.contract.account().address()).to_string(); - let signer_balance = self.provider.get_balance(signer).await.unwrap(); - - match cost_estimation { - Ok(cost) => { - let max_cost = U256::from(cost.total_fee); - return Some(max_cost.saturating_sub(signer_balance)); + match simulate_call { + Ok(simulation) => { + let signer = Address::from(self.contract.account().address()).to_string(); + let signer_balance = self.provider.get_balance(signer).await; + if let Err(err) = signer_balance { + trace!("Failed to get signer balance: {:?}", err); + return None; + } + Some(U256::from(simulation.gas_used).saturating_sub(signer_balance.unwrap())) } Err(err) => { - trace!("Failed to estimate transaction cost: {:?}", err); + trace!("Failed to simulate validator announcement: {:?}", err); return None; } } From 9988d2c508921a52f7f7738296c9a58b73c07319 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Tue, 12 Nov 2024 10:06:39 +0100 Subject: [PATCH 11/31] chore(fuel-integration): add todo for the MerkleTreeHook Fix --- rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index e7a1a492af..f0e4298832 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -47,6 +47,7 @@ impl FuelMerkleTreeHook { }) } + /// TODO this is inaccurate, fix this /// Simulate lag on call /// Since we have no way of querying point in time data, we can only simulate lag /// by sleeping for the lag amount of time. As lag is usually 1 based on the re-org @@ -233,6 +234,8 @@ impl SequenceAwareIndexer for FuelMerkleTreeHookIndexer { // this would mess up if there are mutiple count updates per block // in that case we can store the amount of updates per block as well + // TODO: for block numbers we an just sub the lag from the block number + self.contract .methods() .count_and_block() From edc077ddd1d0cb7c3d70c49de6f2c605193d6962 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Thu, 14 Nov 2024 16:19:44 +0100 Subject: [PATCH 12/31] feat(merkle): merkle tree hook with enforced finality --- .../abis/MerkleTreeHook.abi.json | 74 ++++++++++++++----- .../chains/hyperlane-fuel/src/conversions.rs | 6 +- .../hyperlane-fuel/src/interchain_gas.rs | 20 +++-- .../main/chains/hyperlane-fuel/src/mailbox.rs | 5 +- .../hyperlane-fuel/src/merkle_tree_hook.rs | 41 ++++------ .../chains/hyperlane-fuel/src/provider.rs | 2 + 6 files changed, 88 insertions(+), 60 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json index a730cae86f..d7cf271c9f 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json @@ -28,17 +28,17 @@ { "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5", - "metadataTypeId": 3 + "metadataTypeId": 2 }, { "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", "concreteTypeId": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", - "metadataTypeId": 4 + "metadataTypeId": 3 }, { "type": "enum merkle::MerkleError", "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb", - "metadataTypeId": 5 + "metadataTypeId": 4 }, { "type": "struct interfaces::merkle_tree_hook::InsertedIntoTreeEvent", @@ -98,19 +98,9 @@ } ] }, - { - "type": "[_; 32]", - "metadataTypeId": 2, - "components": [ - { - "name": "__array_element", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - } - ] - }, { "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", - "metadataTypeId": 3, + "metadataTypeId": 2, "components": [ { "name": "MessageNotDispatching", @@ -132,7 +122,7 @@ }, { "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", - "metadataTypeId": 4, + "metadataTypeId": 3, "components": [ { "name": "UNUSED", @@ -182,7 +172,7 @@ }, { "type": "enum merkle::MerkleError", - "metadataTypeId": 5, + "metadataTypeId": 4, "components": [ { "name": "MerkleTreeFull", @@ -190,6 +180,10 @@ } ] }, + { + "type": "generic T", + "metadataTypeId": 5 + }, { "type": "raw untyped ptr", "metadataTypeId": 6 @@ -214,7 +208,13 @@ "components": [ { "name": "branch", - "typeId": 2 + "typeId": 13, + "typeArguments": [ + { + "name": "", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] }, { "name": "count", @@ -259,6 +259,46 @@ "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 12, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 13, + "components": [ + { + "name": "buf", + "typeId": 12, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] } ], "functions": [ diff --git a/rust/main/chains/hyperlane-fuel/src/conversions.rs b/rust/main/chains/hyperlane-fuel/src/conversions.rs index 134fe7f17e..07c0a67fe9 100644 --- a/rust/main/chains/hyperlane-fuel/src/conversions.rs +++ b/rust/main/chains/hyperlane-fuel/src/conversions.rs @@ -1,6 +1,5 @@ -use hyperlane_core::{ModuleType, H160, H256}; - use fuels::types::{Bits256, EvmAddress}; +use hyperlane_core::{ModuleType, H160, H256}; /// Wrapper around the Fuel ModuleType enum. pub struct IsmType(pub crate::contracts::interchain_security_module::ModuleType); @@ -11,8 +10,9 @@ pub trait FromBits256Array { fn into_h256_array(self) -> [H256; 32]; } -impl FromBits256Array for [Bits256; 32] { +impl FromBits256Array for Vec { fn into_h256_array(self) -> [H256; 32] { + assert!(self.len() == 32); let mut h256_array: [H256; 32] = [H256::zero(); 32]; for (i, bits256) in self.iter().enumerate() { h256_array[i] = H256::from(bits256.0); diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs index 277f4825f5..4afbb2700c 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs @@ -1,19 +1,17 @@ -use crate::contracts::interchain_gas_paymaster::GasPaymentEvent; use crate::{ - contracts::interchain_gas_paymaster::InterchainGasPaymaster as InterchainGasPaymasterContract, - conversions::*, FuelProvider, + contracts::interchain_gas_paymaster::{ + GasPaymentEvent, InterchainGasPaymaster as InterchainGasPaymasterContract, + }, + conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, }; -use crate::{ConnectionConf, FuelIndexer}; use async_trait::async_trait; -use fuels::accounts::wallet::WalletUnlocked; -use fuels::types::bech32::Bech32ContractId; -use fuels::types::transaction_response::TransactionResponse; -use fuels::types::Bytes32; +use fuels::{accounts::wallet::WalletUnlocked, types::bech32::Bech32ContractId}; use hyperlane_core::{ - ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, Indexed, Indexer, - InterchainGasPaymaster, SequenceAwareIndexer, U256, + ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, + HyperlaneProvider, Indexed, Indexer, InterchainGasPaymaster, InterchainGasPayment, LogMeta, + SequenceAwareIndexer, H256, }; -use hyperlane_core::{HyperlaneDomain, HyperlaneProvider, InterchainGasPayment, LogMeta, H256}; use std::ops::RangeInclusive; /// A reference to an IGP contract on some Fuel chain diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 58fdca5b42..852c36b2d9 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -8,10 +8,7 @@ use fuels::{ prelude::{Bech32ContractId, WalletUnlocked}, programs::calls::Execution, tx::{Receipt, ScriptExecutionResult}, - types::{ - transaction::TxPolicies, transaction_builders::VariableOutputPolicy, - transaction_response::TransactionResponse, Bytes, Bytes32, - }, + types::{transaction::TxPolicies, transaction_builders::VariableOutputPolicy, Bytes}, }; use hyperlane_core::{ utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 3aa9bbc6ef..51b417bd63 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -7,18 +7,18 @@ use crate::{ }; use async_trait::async_trait; use fuels::{ - accounts::wallet::WalletUnlocked, - programs::calls::Execution, - types::{bech32::Bech32ContractId, transaction_response::TransactionResponse, Bytes32}, + accounts::wallet::WalletUnlocked, programs::calls::Execution, types::bech32::Bech32ContractId, }; use hyperlane_core::{ accumulator::incremental::IncrementalMerkle, ChainCommunicationError, ChainResult, Checkpoint, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, LogMeta, MerkleTreeHook, MerkleTreeInsertion, SequenceAwareIndexer, H256, - U256, }; use std::{num::NonZeroU64, ops::RangeInclusive}; +/// Smart contract level enforced finality +const ENFORCED_FINALITY: u8 = 1; + /// A reference to a AggregationIsm contract on some Fuel chain #[derive(Debug)] pub struct FuelMerkleTreeHook { @@ -46,15 +46,15 @@ impl FuelMerkleTreeHook { }) } - /// TODO this is inaccurate, fix this - /// Simulate lag on call - /// Since we have no way of querying point in time data, we can only simulate lag - /// by sleeping for the lag amount of time. As lag is usually 1 based on the re-org - /// we would normally sleep for 1 second. - async fn simulate_lag(&self, lag: Option) { - if let Some(lag) = lag { - tokio::time::sleep(std::time::Duration::from_secs(lag.get())).await; - } + /// Asserts the lag + /// The lag or re-org of FuelVM should be set to 1, as it is the solf finality + /// Also, since we cannot query point in time, the lag is built into the contract code + fn assert_lag(&self, lag: Option) { + assert!( + lag.is_some_and(|lag| lag.get() == ENFORCED_FINALITY as u64), + "FuelVM lag should always be {:?}", + ENFORCED_FINALITY + ); } } @@ -77,7 +77,7 @@ impl HyperlaneChain for FuelMerkleTreeHook { #[async_trait] impl MerkleTreeHook for FuelMerkleTreeHook { async fn tree(&self, lag: Option) -> ChainResult { - self.simulate_lag(lag).await; + self.assert_lag(lag); self.contract .methods() @@ -95,7 +95,7 @@ impl MerkleTreeHook for FuelMerkleTreeHook { } async fn count(&self, lag: Option) -> ChainResult { - self.simulate_lag(lag).await; + self.assert_lag(lag); self.contract .methods() @@ -107,7 +107,7 @@ impl MerkleTreeHook for FuelMerkleTreeHook { } async fn latest_checkpoint(&self, lag: Option) -> ChainResult { - self.simulate_lag(lag).await; + self.assert_lag(lag); self.contract .methods() @@ -174,15 +174,6 @@ impl Indexer for FuelMerkleTreeHookIndexer { #[async_trait] impl SequenceAwareIndexer for FuelMerkleTreeHookIndexer { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { - // TODO make sure the block is finalized, somehow - // Could make a function in sway that checks the stored last count update, - // if the last count update is the current block, then we return count-1 and block-1 - // else we return count and block - // this would mess up if there are mutiple count updates per block - // in that case we can store the amount of updates per block as well - - // TODO: for block numbers we an just sub the lag from the block number - self.contract .methods() .count_and_block() diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index 4e5a456a4a..6c38e136bf 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -47,11 +47,13 @@ impl FuelProvider { } /// Get the finalized block number + /// We subtract 1 from the latest block height to get the finalized block number pub async fn get_finalized_block_number(&self) -> ChainResult { self.provider .latest_block_height() .await .map_err(ChainCommunicationError::from_other) + .map(|block| block - 1) } } From edb0b629a1d1527d955d49353a29593dd88e70a7 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Thu, 14 Nov 2024 17:30:54 +0100 Subject: [PATCH 13/31] feat(fuel-integration): clippy fixes --- .../main/chains/hyperlane-fuel/src/indexer.rs | 30 +++++++------------ rust/main/chains/hyperlane-fuel/src/lib.rs | 5 +--- .../main/chains/hyperlane-fuel/src/mailbox.rs | 8 ++--- .../chains/hyperlane-fuel/src/provider.rs | 18 +++++------ .../hyperlane-fuel/src/validator_announce.rs | 4 +-- rust/main/utils/abigen/src/lib.rs | 3 +- 6 files changed, 23 insertions(+), 45 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs index df039f2877..05d49beed7 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer.rs @@ -21,8 +21,6 @@ use std::{ ops::{Deref, RangeInclusive}, }; -// TODO, clippy issues - /// A Fuel Indexer supporting a specific event type. /// The generic `E` is the type of the event this indexer will be filtering and parsing. /// @@ -69,7 +67,6 @@ where let contract_address = Bech32ContractId::from_h256(&locator.address); let decoder = E::log_decoder(contract_address.clone(), wallet); - let fn_decoder = decoder.clone(); Self { fuel_provider, @@ -91,7 +88,7 @@ where { let (block_cursor, transaction_cursor) = self.get_sync_cursors(&range).await?; - let (transaction_amount, transaction_map) = self + let transaction_map = self .get_block_data(range.clone(), block_cursor.clone()) .await?; @@ -175,7 +172,6 @@ where /// Check if a transaction is from a contract /// @note: Only works for checking script transactions - #[allow(clippy::get_first)] fn is_transaction_from_contract(&self, res: &TransactionResponse) -> bool { if let TransactionType::Script(script_transaction) = &res.transaction { if script_transaction.inputs().iter().any(|input| { @@ -210,13 +206,13 @@ where let mut transaction_data = Vec::new(); for (tx_data, tx_id) in transactions.results.iter().zip(transaction_ids) { - transaction_data.push((tx_id.clone(), tx_data.clone())); + transaction_data.push((tx_id, tx_data.clone())); } let filtered_transactions = transaction_data .into_iter() .filter(|(_, tx_data)| { - self.is_transaction_from_contract(&tx_data) && self.has_event(tx_data) + self.is_transaction_from_contract(tx_data) && self.has_event(tx_data) }) .collect::>(); @@ -227,7 +223,7 @@ where &self, range: RangeInclusive, cursor: Option, - ) -> ChainResult<(i32, HashMap)> { + ) -> ChainResult> { let result_amount: u32 = range.end() - range.start(); let req = PaginationRequest { cursor, @@ -243,23 +239,17 @@ where .map_err(ChainCommunicationError::from_other)?; let mut transaction_map: HashMap = HashMap::new(); - blocks.results.iter().for_each(|block| { + blocks.results.into_iter().for_each(|block| { block .transactions - .iter() + .into_iter() .enumerate() .for_each(|(index, tx)| { - transaction_map.insert(tx.clone(), (block.id, index as u64)); + transaction_map.insert(tx, (block.id, index as u64)); }); }); - let transaction_amount = blocks - .results - .iter() - .fold(0, |acc: usize, block| acc + block.transactions.len()) - as i32; - - Ok((transaction_amount, transaction_map)) + Ok(transaction_map) } async fn get_sync_cursors( @@ -297,11 +287,11 @@ where }; let hex_block = hex::encode(range_start.to_be_bytes()); - let hex_tx = hex::encode(first_transaction.to_vec()); + let hex_tx = hex::encode(first_transaction); let tx_cursor = Some(format!("{}#0x{}", hex_block, hex_tx)); let block_cursor = Some(range_start.to_string()); - return Ok((block_cursor, tx_cursor)); + Ok((block_cursor, tx_cursor)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/lib.rs b/rust/main/chains/hyperlane-fuel/src/lib.rs index a4a1778876..40acc665a1 100644 --- a/rust/main/chains/hyperlane-fuel/src/lib.rs +++ b/rust/main/chains/hyperlane-fuel/src/lib.rs @@ -1,9 +1,6 @@ -//! Implementation of hyperlane for fuel. - +//! Implementation of Hyperlane for Fuel. #![forbid(unsafe_code)] #![warn(missing_docs)] -// TODO: Remove once we start filling things in -#![allow(unused_variables)] pub use self::{ aggregation_ism::*, indexer::*, interchain_gas::*, interchain_security_module::*, mailbox::*, diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 852c36b2d9..86904c531c 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -232,9 +232,8 @@ impl Mailbox for FuelMailbox { }) } - fn process_calldata(&self, message: &HyperlaneMessage, metadata: &[u8]) -> Vec { - // Seems like this is not needed for Fuel, as it's only used in mocks - todo!() + fn process_calldata(&self, _message: &HyperlaneMessage, _metadata: &[u8]) -> Vec { + todo!() // not required } } @@ -284,7 +283,7 @@ impl Indexer for FuelMailboxIndexer { impl Indexer for FuelMailboxIndexer { async fn fetch_logs_in_range( &self, - range: RangeInclusive, + _range: RangeInclusive, ) -> ChainResult, LogMeta)>> { todo!() // Needed for scraper } @@ -306,7 +305,6 @@ impl SequenceAwareIndexer for FuelMailboxIndexer { #[async_trait] impl SequenceAwareIndexer for FuelMailboxIndexer { - #[allow(clippy::unnecessary_cast)] // TODO: `rustc` 1.80.1 clippy issue async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { let tip = Indexer::::get_finalized_block_number(&self).await?; diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index 6c38e136bf..efa9ef2936 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -70,13 +70,12 @@ impl HyperlaneChain for FuelProvider { #[async_trait] impl HyperlaneProvider for FuelProvider { /// Used by scraper - #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue async fn get_block_by_hash(&self, hash: &H256) -> ChainResult { let block_res = self .provider .block(&hash.0.into()) .await - .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(hash.clone()))?; + .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(*hash))?; match block_res { Some(block) => Ok(BlockInfo { @@ -84,19 +83,17 @@ impl HyperlaneProvider for FuelProvider { number: block.header.height.into(), timestamp: block.header.time.map_or(0, |t| t.timestamp() as u64), }), - None => Err(ChainCommunicationError::BlockNotFound(hash.clone())), + None => Err(ChainCommunicationError::BlockNotFound(*hash)), } } /// Used by scraper - #[allow(clippy::clone_on_copy)] // TODO: `rustc` 1.80.1 clippy issue - #[allow(clippy::match_like_matches_macro)] // TODO: `rustc` 1.80.1 clippy issue async fn get_txn_by_hash(&self, hash: &H256) -> ChainResult { let transaction_res = self .provider .get_transaction_by_id(&hash.0.into()) .await - .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(hash.clone()))?; + .map_err(|_| HyperlaneProviderError::CouldNotFindObjectByHash(*hash))?; match transaction_res { Some(transaction) => { @@ -115,10 +112,9 @@ impl HyperlaneProvider for FuelProvider { let (sender, recipient, nonce) = match transaction.status { TxStatus::Success { receipts } => { - let valid_receipt = receipts.into_iter().find(|receipt| match receipt { - Receipt::MessageOut { .. } => true, - _ => false, - }); + let valid_receipt = receipts + .into_iter() + .find(|receipt| matches!(receipt, Receipt::MessageOut { .. })); match valid_receipt { Some(Receipt::MessageOut { @@ -145,7 +141,7 @@ impl HyperlaneProvider for FuelProvider { }; Ok(TxnInfo { - hash: hash.clone(), + hash: *hash, gas_limit: gas_limit.into(), max_priority_fee_per_gas: None, max_fee_per_gas: None, diff --git a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs index 340103e5b4..9cfb00f10c 100644 --- a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs +++ b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs @@ -68,9 +68,7 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { ) -> ChainResult>> { self.contract .methods() - .get_announced_storage_locations( - validators.iter().map(|v| Bits256::from_h256(v)).collect(), - ) + .get_announced_storage_locations(validators.iter().map(Bits256::from_h256).collect()) .simulate(Execution::StateReadOnly) .await .map(|res| res.value) diff --git a/rust/main/utils/abigen/src/lib.rs b/rust/main/utils/abigen/src/lib.rs index 3fe21a55bb..eefeb5de29 100644 --- a/rust/main/utils/abigen/src/lib.rs +++ b/rust/main/utils/abigen/src/lib.rs @@ -104,8 +104,7 @@ pub fn generate_bindings( } #[cfg(feature = "fuels")] if build_type == BuildType::Fuels { - let abi = - fuels_code_gen::Abi::load_from(contract_path.as_ref()).expect("could not load abi"); + let abi = fuels_code_gen::Abi::load_from(abi_source).expect("could not load abi"); let tokens = fuels_code_gen::Abigen::generate( vec![fuels_code_gen::AbigenTarget::new( contract_name.into(), From e07d0cde906a87666fd5deccab355a971c7d63b7 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 15 Nov 2024 10:26:09 +0100 Subject: [PATCH 14/31] chore(fuel-provider): decrease nesting --- .../chains/hyperlane-fuel/src/provider.rs | 64 ++++++++++--------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index efa9ef2936..c17018c2bf 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -55,6 +55,34 @@ impl FuelProvider { .map_err(ChainCommunicationError::from_other) .map(|block| block - 1) } + + /// Extract transaction data from receipts + fn extract_transaction_data(receipts: Vec) -> (H256, Option, u64) { + let valid_receipt = receipts + .into_iter() + .find(|receipt| matches!(receipt, Receipt::MessageOut { .. })); + + match valid_receipt { + Some(Receipt::MessageOut { + sender, + recipient, + nonce, + .. + }) => { + let mut arr = [0u8; 8]; + let nonce_bytes = <[u8; 32]>::from(nonce); + arr.copy_from_slice(&nonce_bytes[0..8]); + let parsed_nonce = u64::from_be_bytes(arr); + + ( + <[u8; 32]>::from(sender).into(), + Some(<[u8; 32]>::from(recipient).into()), + parsed_nonce, + ) + } + _ => (H256::zero(), None, 0), + } + } } impl HyperlaneChain for FuelProvider { @@ -111,32 +139,7 @@ impl HyperlaneProvider for FuelProvider { }; let (sender, recipient, nonce) = match transaction.status { - TxStatus::Success { receipts } => { - let valid_receipt = receipts - .into_iter() - .find(|receipt| matches!(receipt, Receipt::MessageOut { .. })); - - match valid_receipt { - Some(Receipt::MessageOut { - sender, - recipient, - nonce, - .. - }) => { - let mut arr = [0u8; 8]; - let nonce_bytes = <[u8; 32]>::from(nonce); - arr.copy_from_slice(&nonce_bytes[0..8]); - let parsed_nonce = u64::from_be_bytes(arr); - - ( - <[u8; 32]>::from(sender).into(), - Some(<[u8; 32]>::from(recipient).into()), - parsed_nonce, - ) - } - _ => (H256::zero(), None, 0), - } - } + TxStatus::Success { receipts } => Self::extract_transaction_data(receipts), _ => (H256::zero(), None, 0), }; @@ -165,7 +168,7 @@ impl HyperlaneProvider for FuelProvider { match contract_res { Ok(contract) => Ok(contract.is_some()), Err(e) => Err(ChainCommunicationError::CustomError(format!( - "Failed to get contract: {}", + "Failed to query contract: {}", e ))), } @@ -173,9 +176,10 @@ impl HyperlaneProvider for FuelProvider { async fn get_balance(&self, address: String) -> ChainResult { let base = self.provider.base_asset_id(); - let address_bytes = hex::decode(address)?; - let address = - *Address::from_bytes_ref_checked(address_bytes.as_slice()).expect("Invalid address"); + let address_bytes = hex::decode(&address)?; + let address = *Address::from_bytes_ref_checked(address_bytes.as_slice()).ok_or( + ChainCommunicationError::CustomError(format!("Invalid address: {}", address)), + )?; self.provider .get_asset_balance(&address.into(), *base) From 45cc4d2f1e41347a0cc6f33dad117e0ded6a9301 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 15 Nov 2024 11:20:57 +0100 Subject: [PATCH 15/31] feat(fuel-integration): add FuelIgnition chain, WIP mainnet/testnet configs --- rust/main/config/mainnet_config.json | 50 +++++++++++++++++++++++++++ rust/main/config/testnet_config.json | 50 +++++++++++++++++++++++++++ rust/main/hyperlane-core/src/chain.rs | 11 +++--- 3 files changed, 106 insertions(+), 5 deletions(-) diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index f0ea1a9ddd..9fb01989bb 100644 --- a/rust/main/config/mainnet_config.json +++ b/rust/main/config/mainnet_config.json @@ -2719,6 +2719,56 @@ "gasPrice": 200000000 } }, + "fueltestnet": { + "blockExplorers": [ + { + "apiUrl": "https://app.fuel.network/", + "family": "other", + "name": "Fuel Explorer", + "url": "https://app.fuel.network/" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 1, + "reorgPeriod": 1 + }, + "chainId": 1717982311, + "deployer": { + "name": "Simply Staking", + "url": "https://simplystaking.com/" + }, + "displayName": "FuelIgnition", + "domainId": 1717982311, + "gasCurrencyCoinGeckoId": "fuel-2", + "name": "fuelignition", + "nativeToken": { + "decimals": 9, + "name": "Ethereum", + "symbol": "ETH" + }, + "protocol": "fuel", + "rpcUrls": [ + { + "http": "https://mainnet.fuel.network/v1/graphql" + } + ], + "mailbox": "", + "postDispatch": "", + "recipient": "", + "interchainSecurityModule": "", + "merkleTreeHook": "", + "storageGasOracle": "", + "interchainGasPaymaster": "", + "interchainGasPaymasterHook": "", + "warpRouteNative": "", + "warpRouteBridged": "", + "validatorAnnounce": "", + "index": { + "from": 0, + "chunk": 10 + } + }, "sei": { "aggregationHook": "0x40514BD46C57455933Be8BAedE96C4F0Ba3507D6", "blockExplorers": [ diff --git a/rust/main/config/testnet_config.json b/rust/main/config/testnet_config.json index e5e01dcaf8..0f85b797ca 100644 --- a/rust/main/config/testnet_config.json +++ b/rust/main/config/testnet_config.json @@ -437,6 +437,56 @@ "interchainAccountRouter": "0x2C6dD6768E669EDB7b53f26067C1C4534862c3de", "timelockController": "0x0000000000000000000000000000000000000000" }, + "fueltestnet": { + "blockExplorers": [ + { + "apiUrl": "https://app-testnet.fuel.network/", + "family": "other", + "name": "Fuel Testnet Explorer", + "url": "https://app-testnet.fuel.network/" + } + ], + "blocks": { + "confirmations": 1, + "estimateBlockTime": 1, + "reorgPeriod": 1 + }, + "chainId": 1717982312, + "deployer": { + "name": "Simply Staking", + "url": "https://simplystaking.com/" + }, + "displayName": "FuelTestnet", + "domainId": 1717982312, + "gasCurrencyCoinGeckoId": "fuel-2", + "name": "fueltestnet", + "nativeToken": { + "decimals": 9, + "name": "Ethereum", + "symbol": "ETH" + }, + "protocol": "fuel", + "rpcUrls": [ + { + "http": "https://testnet.fuel.network/v1/graphql" + } + ], + "mailbox": "0xba28b20003ba7332e9a44b7c96bf08cace0404711fb4df606f41b2bc20b3f830", + "postDispatch": "0xf581318c940ac5c5f42b80bae1d77dd0beb4956ec06d4eeb9dfba537431a8910", + "recipient": "0xaf127490a1ba82cf364c82c7874cb41970c2936017cdfd1e3b3461e0a1afcd86", + "interchainSecurityModule": "0xf3d62e27518753adb4f2e6209cf2949b1eb33a7228ff9a9b25c85a096c71eea8", + "merkleTreeHook": "0xa7cd5cc289e0f4307353f9b5249c4b44b559c50d305c70adfd82e666bc31fa31", + "storageGasOracle": "0x5368f7e405a523aad22a68e45edc744c07e6cf087e72a59cfaccfb2e5d5bd0c8", + "interchainGasPaymaster": "0x142b6b9c045409a40c955c0683ad12f828f1159d290254c97c4e448746a0daf1", + "interchainGasPaymasterHook": "0x4a98830842b3fb00cf7364ae274e4c7a3b4fb5bc4fc56605c54c3eb739708b06", + "warpRouteNative": "0x546bf7faef2ed5b7904026f0f78b21ce8bbe46fb1706e119b209872aedcce851", + "warpRouteBridged": "0x36f77d8e6ca9ac0cc73edd2143d5f5b5d14779f5d685b8b1ef6958bb58b65d68", + "validatorAnnounce": "0x23b714b9895b71c5d9d052a9b8ef32fdbec99f496bef19926e639beaea563cc3", + "index": { + "from": 15563188, + "chunk": 10 + } + }, "fuji": { "aggregationHook": "0x8E9b4006171c6B75111823e7545Ee5400CEce0B3", "blockExplorers": [ diff --git a/rust/main/hyperlane-core/src/chain.rs b/rust/main/hyperlane-core/src/chain.rs index c6826de175..4fda20db96 100644 --- a/rust/main/hyperlane-core/src/chain.rs +++ b/rust/main/hyperlane-core/src/chain.rs @@ -178,6 +178,7 @@ pub enum KnownHyperlaneDomain { Zetachain = 7000, Zircuit = 48900, ZoraMainnet = 7777777, + FuelIgnition = 1717982311, // -- Local chains -- // @@ -321,7 +322,7 @@ impl KnownHyperlaneDomain { InEvm, Injective, Kroma, Linea, Lisk, Lukso, MantaPacific, Mantle, Merlin, Metis, Mint, Mode, Moonbeam, Neutron, Optimism, Osmosis, Polygon, ProofOfPlay, ReAl, Redstone, Sanko, Sei, SolanaMainnet, Taiko, Tangle, Viction, Worldchain, Xai, - Xlayer, Zetachain, Zircuit, ZoraMainnet, + Xlayer, Zetachain, Zircuit, ZoraMainnet, FuelIgnition ], Testnet: [ Alfajores, BinanceSmartChainTestnet, Chiado, ConnextSepolia, Fuji, Holesky, MoonbaseAlpha, @@ -353,7 +354,7 @@ impl KnownHyperlaneDomain { ScrollSepolia, Sepolia, SuperpositionTestnet ], - HyperlaneDomainProtocol::Fuel: [FuelTest1, FuelTestnet], + HyperlaneDomainProtocol::Fuel: [FuelTest1, FuelTestnet, FuelIgnition], HyperlaneDomainProtocol::Sealevel: [EclipseMainnet, SolanaMainnet, SealevelTest1, SealevelTest2], HyperlaneDomainProtocol::Cosmos: [ Injective, Neutron, Osmosis, @@ -388,15 +389,15 @@ impl KnownHyperlaneDomain { HyperlaneDomainTechnicalStack::Other: [ Avalanche, BinanceSmartChain, Celo, EclipseMainnet, Endurance, Ethereum, FuseMainnet, Gnosis, Injective, Linea, Lukso, Neutron, Osmosis, Polygon, - Sei, SolanaMainnet, Taiko, Viction, Zetachain, + Sei, SolanaMainnet, Taiko, Viction, Zetachain, FuelIgnition, // Local chains CosmosTest99990, CosmosTest99991, FuelTest1, SealevelTest1, SealevelTest2, Test1, - Test2, Test3, FuelTestnet, + Test2, Test3, // Test chains Alfajores, BinanceSmartChainTestnet, Chiado, Fuji, Holesky, MoonbaseAlpha, ScrollSepolia, - Sepolia + Sepolia, FuelTestnet ], }) } From 4d91002bb663bb30e898525f61eeea4cfade4f42 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 18 Nov 2024 13:20:10 +0100 Subject: [PATCH 16/31] chore(fue-integration): spelling error in comment --- rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 5a58f74f0e..277495323d 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -48,7 +48,7 @@ impl FuelMerkleTreeHook { } /// Asserts the lag - /// The lag or re-org of FuelVM should be set to 1, as it is the solf finality + /// The lag or re-org of FuelVM should be set to 1, as it is the soft finality /// Also, since we cannot query point in time, the lag is built into the contract code fn assert_lag(&self, reorg_period: &ReorgPeriod) { assert!( From b649fa9dd595f45eaed960909c4cb52f8e647397 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 18 Nov 2024 13:22:40 +0100 Subject: [PATCH 17/31] chore(fue-integration): remove useless & --- rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 277495323d..44214abb3a 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -110,7 +110,7 @@ impl MerkleTreeHook for FuelMerkleTreeHook { } async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult { - self.assert_lag(&reorg_period); + self.assert_lag(reorg_period); self.contract .methods() From 1e43076272e9814ef5735d26ae63c14cedfdc5d2 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 20 Nov 2024 11:13:04 +0100 Subject: [PATCH 18/31] feat(fuelvm-integration): reorg logic --- rust/main/agents/relayer/src/relayer.rs | 1 + rust/main/agents/validator/src/validator.rs | 1 + .../abis/MerkleTreeHook.abi.json | 2 +- .../main/chains/hyperlane-fuel/src/mailbox.rs | 7 +---- .../hyperlane-fuel/src/merkle_tree_hook.rs | 30 +++---------------- rust/main/config/mainnet_config.json | 2 +- rust/main/config/testnet_config.json | 2 +- rust/main/hyperlane-base/src/settings/base.rs | 17 ++++++++++- 8 files changed, 26 insertions(+), 36 deletions(-) diff --git a/rust/main/agents/relayer/src/relayer.rs b/rust/main/agents/relayer/src/relayer.rs index 1ac619792c..d612c1639c 100644 --- a/rust/main/agents/relayer/src/relayer.rs +++ b/rust/main/agents/relayer/src/relayer.rs @@ -135,6 +135,7 @@ impl BaseAgent for Relayer { .map(|origin| (origin.clone(), HyperlaneRocksDB::new(origin, db.clone()))) .collect::>(); + settings.check_fuel_reorg(); let mailboxes = settings .build_mailboxes(settings.destination_chains.iter(), &core_metrics) .await?; diff --git a/rust/main/agents/validator/src/validator.rs b/rust/main/agents/validator/src/validator.rs index 2d09bd93ff..704d6767ee 100644 --- a/rust/main/agents/validator/src/validator.rs +++ b/rust/main/agents/validator/src/validator.rs @@ -76,6 +76,7 @@ impl BaseAgent for Validator { // Intentionally using hyperlane_ethereum for the validator's signer let (signer_instance, signer) = SingletonSigner::new(settings.validator.build().await?); + settings.check_fuel_reorg(); let core = settings.build_hyperlane_core(metrics.clone()); let checkpoint_syncer = settings .checkpoint_syncer diff --git a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json index d7cf271c9f..7f123f9b3e 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json @@ -353,7 +353,7 @@ { "name": "doc-comment", "arguments": [ - " Gets the stored count of the MerkleTree library." + " Gets the stored count of the MerkleTree." ] }, { diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index d164788cc9..ebf1ca3915 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -21,7 +21,6 @@ use std::{ fmt::{Debug, Formatter}, ops::RangeInclusive, }; - use tracing::{instrument, warn}; const GAS_ESTIMATE_MULTIPLIER: f64 = 1.3; @@ -78,11 +77,7 @@ impl Debug for FuelMailbox { impl Mailbox for FuelMailbox { #[instrument(level = "debug", err, ret, skip(self))] #[allow(clippy::blocks_in_conditions)] // TODO: `rustc` 1.80.1 clippy issue - async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult { - assert!( - reorg_period.is_none(), - "Fuel does not support querying point-in-time" - ); + async fn count(&self, _reorg_period: &ReorgPeriod) -> ChainResult { self.contract .methods() .nonce() diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 44214abb3a..11b2722b67 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -17,10 +17,7 @@ use hyperlane_core::{ }; use std::ops::RangeInclusive; -/// Smart contract level enforced finality -const ENFORCED_FINALITY: u8 = 1; - -/// A reference to a AggregationIsm contract on some Fuel chain +/// A reference to a MerkleTreeHook contract on some Fuel chain #[derive(Debug)] pub struct FuelMerkleTreeHook { contract: MerkleTreeHookContract, @@ -46,19 +43,6 @@ impl FuelMerkleTreeHook { provider: fuel_provider, }) } - - /// Asserts the lag - /// The lag or re-org of FuelVM should be set to 1, as it is the soft finality - /// Also, since we cannot query point in time, the lag is built into the contract code - fn assert_lag(&self, reorg_period: &ReorgPeriod) { - assert!( - reorg_period - .as_blocks() - .is_ok_and(|reorg| reorg == ENFORCED_FINALITY as u32), - "FuelVM lag should always be {:?}", - ENFORCED_FINALITY - ); - } } impl HyperlaneContract for FuelMerkleTreeHook { @@ -79,9 +63,7 @@ impl HyperlaneChain for FuelMerkleTreeHook { #[async_trait] impl MerkleTreeHook for FuelMerkleTreeHook { - async fn tree(&self, reorg_period: &ReorgPeriod) -> ChainResult { - self.assert_lag(reorg_period); - + async fn tree(&self, _reorg_period: &ReorgPeriod) -> ChainResult { self.contract .methods() .tree() @@ -97,9 +79,7 @@ impl MerkleTreeHook for FuelMerkleTreeHook { }) } - async fn count(&self, reorg_period: &ReorgPeriod) -> ChainResult { - self.assert_lag(reorg_period); - + async fn count(&self, _reorg_period: &ReorgPeriod) -> ChainResult { self.contract .methods() .count() @@ -109,9 +89,7 @@ impl MerkleTreeHook for FuelMerkleTreeHook { .map(|res| res.value) } - async fn latest_checkpoint(&self, reorg_period: &ReorgPeriod) -> ChainResult { - self.assert_lag(reorg_period); - + async fn latest_checkpoint(&self, _reorg_period: &ReorgPeriod) -> ChainResult { self.contract .methods() .latest_checkpoint() diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index 9fb01989bb..b1aa58cb3f 100644 --- a/rust/main/config/mainnet_config.json +++ b/rust/main/config/mainnet_config.json @@ -2731,7 +2731,7 @@ "blocks": { "confirmations": 1, "estimateBlockTime": 1, - "reorgPeriod": 1 + "reorgPeriod": 0 }, "chainId": 1717982311, "deployer": { diff --git a/rust/main/config/testnet_config.json b/rust/main/config/testnet_config.json index 0f85b797ca..25761985d6 100644 --- a/rust/main/config/testnet_config.json +++ b/rust/main/config/testnet_config.json @@ -449,7 +449,7 @@ "blocks": { "confirmations": 1, "estimateBlockTime": 1, - "reorgPeriod": 1 + "reorgPeriod": 0 }, "chainId": 1717982312, "deployer": { diff --git a/rust/main/hyperlane-base/src/settings/base.rs b/rust/main/hyperlane-base/src/settings/base.rs index 6757a545ed..32e8823786 100644 --- a/rust/main/hyperlane-base/src/settings/base.rs +++ b/rust/main/hyperlane-base/src/settings/base.rs @@ -3,10 +3,11 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash, sync::Arc}; use eyre::{eyre, Context, Result}; use futures_util::future::try_join_all; use hyperlane_core::{ - HyperlaneChain, HyperlaneDomain, HyperlaneLogStore, HyperlaneProvider, + HyperlaneChain, HyperlaneDomain, HyperlaneDomainProtocol, HyperlaneLogStore, HyperlaneProvider, HyperlaneSequenceAwareIndexerStoreReader, HyperlaneWatermarkedLogStore, InterchainGasPaymaster, Mailbox, MerkleTreeHook, MultisigIsm, SequenceAwareIndexer, ValidatorAnnounce, H256, }; +use tracing::warn; use crate::{ cursors::{CursorType, Indexable}, @@ -81,6 +82,20 @@ impl Settings { .ok_or_else(|| eyre!("No chain setup found for {domain}")) } + /// Check and warn if reorg period is set for FuelVM domains. + pub fn check_fuel_reorg(&self) { + self.chains.values().into_iter().for_each(|conf| { + if conf.domain.domain_protocol() == HyperlaneDomainProtocol::Fuel { + if !conf.reorg_period.is_none() { + warn!( + "Reorg period is set for fuel domain {:?}. FuelVM chains are implemented with instant finality", + conf.domain + ); + } + } + }); + } + /// Try to get the domain for a given chain by name. pub fn lookup_domain(&self, chain_name: &str) -> Result { self.chains From 151ead85979ed4a2825080ec6365b591d2621094 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Mon, 25 Nov 2024 18:45:16 +0100 Subject: [PATCH 19/31] fix(fuel-integration): configs and get finalized block fn --- rust/main/chains/hyperlane-fuel/src/provider.rs | 3 +-- rust/main/config/mainnet_config.json | 2 +- rust/main/config/testnet_config.json | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index 7d1ee45dc3..5a3cb7ee3f 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -47,13 +47,12 @@ impl FuelProvider { } /// Get the finalized block number - /// We subtract 1 from the latest block height to get the finalized block number + /// Since FuelVM has instant finality, this is the same as the latest block number pub async fn get_finalized_block_number(&self) -> ChainResult { self.provider .latest_block_height() .await .map_err(ChainCommunicationError::from_other) - .map(|block| block - 1) } /// Extract transaction data from receipts diff --git a/rust/main/config/mainnet_config.json b/rust/main/config/mainnet_config.json index b1aa58cb3f..93f06fb3f0 100644 --- a/rust/main/config/mainnet_config.json +++ b/rust/main/config/mainnet_config.json @@ -2719,7 +2719,7 @@ "gasPrice": 200000000 } }, - "fueltestnet": { + "fuelignition": { "blockExplorers": [ { "apiUrl": "https://app.fuel.network/", diff --git a/rust/main/config/testnet_config.json b/rust/main/config/testnet_config.json index 25761985d6..5888851da5 100644 --- a/rust/main/config/testnet_config.json +++ b/rust/main/config/testnet_config.json @@ -456,6 +456,7 @@ "name": "Simply Staking", "url": "https://simplystaking.com/" }, + "isTestnet": true, "displayName": "FuelTestnet", "domainId": 1717982312, "gasCurrencyCoinGeckoId": "fuel-2", From ca463ea47074ff3a76a3073fd9ee3d3365a6792d Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 4 Dec 2024 10:02:06 +0100 Subject: [PATCH 20/31] feat(scraper): FuelVM support --- rust/main/Cargo.lock | 192 ++- rust/main/Cargo.toml | 4 + rust/main/agents/scraper/README.md | 6 +- .../m20230309_000001_create_table_domain.rs | 16 + rust/main/agents/scraper/src/agent.rs | 1 + rust/main/chains/hyperlane-fuel/Cargo.toml | 6 + .../hyperlane-fuel/abis/Mailbox.abi.json | 86 +- rust/main/chains/hyperlane-fuel/build.rs | 6 + .../main/chains/hyperlane-fuel/src/indexer.rs | 297 ---- .../{indexer_events.rs => indexer/events.rs} | 48 +- .../chains/hyperlane-fuel/src/indexer/mod.rs | 178 +++ .../src/indexer/query/conversions.rs | 334 +++++ .../hyperlane-fuel/src/indexer/query/mod.rs | 98 ++ .../src/indexer/query/schemas/fuel.graphql | 1298 +++++++++++++++++ .../hyperlane-fuel/src/indexer/query/types.rs | 257 ++++ .../hyperlane-fuel/src/interchain_gas.rs | 22 +- rust/main/chains/hyperlane-fuel/src/lib.rs | 1 - .../main/chains/hyperlane-fuel/src/mailbox.rs | 105 +- .../chains/hyperlane-fuel/src/provider.rs | 172 ++- .../hyperlane-base/src/settings/chains.rs | 9 +- 20 files changed, 2640 insertions(+), 496 deletions(-) delete mode 100644 rust/main/chains/hyperlane-fuel/src/indexer.rs rename rust/main/chains/hyperlane-fuel/src/{indexer_events.rs => indexer/events.rs} (80%) create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer/mod.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer/query/mod.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer/query/schemas/fuel.graphql create mode 100644 rust/main/chains/hyperlane-fuel/src/indexer/query/types.rs diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index d64ab40996..8b2942fed6 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -666,6 +666,12 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bigdecimal" version = "0.3.1" @@ -2021,7 +2027,7 @@ version = "2.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1afa0591b1021e427e548a1f0f147fe6168f6c7c7f7006bace77f28856051b8" dependencies = [ - "cynic-proc-macros", + "cynic-proc-macros 2.2.8", "reqwest", "serde", "serde_json", @@ -2029,6 +2035,19 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cynic" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a41762e03383d7bf4213b9b4e5fb15e232853400b0b738b764d1d2df9649400" +dependencies = [ + "cynic-proc-macros 3.9.0", + "ref-cast", + "serde", + "static_assertions 1.1.0", + "thiserror", +] + [[package]] name = "cynic-codegen" version = "2.2.8" @@ -2045,16 +2064,56 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cynic-codegen" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b9e35b6ceec97e397c422585aa7d8c057158c63d2727f15d4ddc47563862798" +dependencies = [ + "cynic-parser", + "darling 0.20.10", + "once_cell", + "ouroboros 0.18.4", + "proc-macro2 1.0.86", + "quote 1.0.37", + "strsim 0.10.0", + "syn 2.0.77", + "thiserror", +] + +[[package]] +name = "cynic-parser" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b33b82bcdeebc7a3111be52b1a6a582206ff18d2811dd8575be9809cf6d4c88e" +dependencies = [ + "indexmap 2.5.0", + "lalrpop-util", + "logos", +] + [[package]] name = "cynic-proc-macros" version = "2.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa595c4ed7a5374e0e58c5c34f9d93bd6b7d45062790963bd4b4c3c0bf520c4d" dependencies = [ - "cynic-codegen", + "cynic-codegen 2.2.8", "syn 1.0.109", ] +[[package]] +name = "cynic-proc-macros" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb9f1756c97b93a7e2faf9c5d58cc21655de6a32984dd8aa7aa076c7e246601" +dependencies = [ + "cynic-codegen 3.9.0", + "darling 0.20.10", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "darling" version = "0.13.4" @@ -3375,13 +3434,13 @@ dependencies = [ [[package]] name = "fuel-core-client" -version = "0.40.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09b3a35e82226d77b10653829beb508dc4bcf698fbdaa96610faf894e794444" +checksum = "baf616cb1dd1e0aaa9e60b9e04ab1581ee7f4703c1f9a534a022ac644a05076d" dependencies = [ "anyhow", "base64 0.22.1", - "cynic", + "cynic 2.2.8", "derive_more 0.99.18", "eventsource-client", "fuel-core-types", @@ -3473,15 +3532,16 @@ dependencies = [ [[package]] name = "fuel-core-types" -version = "0.40.0" +version = "0.40.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ee3a95b189bf729d21354a761862bb481298cbd883550adc3fef1bc7beb0b67" +checksum = "409f7eb0e24acd055fe6412376c781e884457f3cddeb18ed618406175e18cfdd" dependencies = [ "anyhow", "bs58 0.5.1", "derivative", "derive_more 0.99.18", "fuel-vm", + "k256 0.13.4", "rand 0.8.5", "secrecy", "serde", @@ -3635,7 +3695,7 @@ checksum = "49fee90e8f3a4fc9392a6cde3010c561fa50da0f805d66fdb659eaa4d5d8a504" dependencies = [ "async-trait", "chrono", - "cynic", + "cynic 2.2.8", "elliptic-curve 0.13.8", "eth-keystore", "fuel-core-client", @@ -4611,10 +4671,16 @@ dependencies = [ "abigen", "anyhow", "async-trait", + "cynic 3.9.0", + "cynic-codegen 3.9.0", + "derive_more 0.99.18", + "fuel-core-client", + "fuel-core-types", "fuels", "futures", "hex 0.4.3", "hyperlane-core", + "reqwest", "serde", "thiserror", "tokio", @@ -5137,6 +5203,15 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "lalrpop-util" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feee752d43abd0f4807a921958ab4131f692a44d4d599733d4419c5d586176ce" +dependencies = [ + "rustversion", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -5294,6 +5369,39 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +[[package]] +name = "logos" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c6b6e02facda28ca5fb8dbe4b152496ba3b1bd5a4b40bb2b1b2d8ad74e0f39b" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b32eb6b5f26efacd015b000bfc562186472cd9b34bdba3f6b264e2a052676d10" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2 1.0.86", + "quote 1.0.37", + "regex-syntax 0.8.4", + "syn 2.0.77", +] + +[[package]] +name = "logos-derive" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e5d0c5463c911ef55624739fc353238b4e310f0144be1f875dc42fec6bfd5ec" +dependencies = [ + "logos-codegen", +] + [[package]] name = "lz4-sys" version = "1.10.0" @@ -5983,7 +6091,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1358bd1558bd2a083fed428ffeda486fbfb323e698cdda7794259d592ca72db" dependencies = [ "aliasable", - "ouroboros_macro", + "ouroboros_macro 0.15.6", +] + +[[package]] +name = "ouroboros" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "944fa20996a25aded6b4795c6d63f10014a7a83f8be9828a11860b08c5fc4a67" +dependencies = [ + "aliasable", + "ouroboros_macro 0.18.4", + "static_assertions 1.1.0", ] [[package]] @@ -5999,6 +6118,20 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ouroboros_macro" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" +dependencies = [ + "heck 0.4.1", + "itertools 0.12.1", + "proc-macro2 1.0.86", + "proc-macro2-diagnostics", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "overload" version = "0.1.1" @@ -6514,6 +6647,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proc-macro2-diagnostics" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", + "version_check", + "yansi", +] + [[package]] name = "prometheus" version = "0.13.4" @@ -6941,6 +7087,26 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ref-cast" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf0a6f84d5f1d581da8b41b47ec8600871962f2a528115b542b362d4b744931" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "regex" version = "1.10.6" @@ -7746,7 +7912,7 @@ dependencies = [ "chrono", "futures", "log", - "ouroboros", + "ouroboros 0.15.6", "rust_decimal", "sea-orm-macros", "sea-query", @@ -11001,6 +11167,12 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + [[package]] name = "yasna" version = "0.5.2" diff --git a/rust/main/Cargo.toml b/rust/main/Cargo.toml index bc9e5620e0..d1d3b03671 100644 --- a/rust/main/Cargo.toml +++ b/rust/main/Cargo.toml @@ -65,6 +65,10 @@ eyre = "=0.6.8" fixed-hash = "0.8.0" fuels = { version = "0.66.9", features = ["coin-cache"] } fuels-code-gen = "0.66.9" +cynic = "3.9.0" +cynic-codegen = { version = "3" } +fuel-core-client = "0.40.1" +fuel-core-types = "0.40.1" futures = "0.3" futures-util = "0.3" generic-array = { version = "0.14", features = ["serde", "more_lengths"] } diff --git a/rust/main/agents/scraper/README.md b/rust/main/agents/scraper/README.md index b36b6403c1..762a3deab1 100644 --- a/rust/main/agents/scraper/README.md +++ b/rust/main/agents/scraper/README.md @@ -11,19 +11,19 @@ docker stop scraper docker rm -v scraper ``` -To init the database, run from `rust` dir +To init the database, run from `rust/main` dir ```bash cargo run --package migration --bin init-db ``` -To re-create the database, run from `rust` dir +To re-create the database, run from `rust/main` dir ```bash cargo run --package migration --bin recreate-db ``` -To re-generate the sea-orm entity code, when no database is running in docker and from the `rust` dir, run +To re-generate the sea-orm entity code, when no database is running in docker and from the `rust/main` dir, run ```bash cargo run --package migration --bin generate-entities diff --git a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs index 848bb05e48..73e03551ee 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs @@ -462,6 +462,22 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: true, is_deprecated: false, }, + RawDomain { + name: "fueltestnet", + token: "ETH", + domain: 1717982312, + chain_id: 1717982312, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "fuelignition", + token: "ETH", + domain: 1717982311, + chain_id: 1717982311, + is_test_net: false, + is_deprecated: false, + }, ]; #[derive(DeriveMigrationName)] diff --git a/rust/main/agents/scraper/src/agent.rs b/rust/main/agents/scraper/src/agent.rs index fd9afc6d7c..171475d8e8 100644 --- a/rust/main/agents/scraper/src/agent.rs +++ b/rust/main/agents/scraper/src/agent.rs @@ -52,6 +52,7 @@ impl BaseAgent for Scraper { Self: Sized, { let db = ScraperDb::connect(&settings.db).await?; + settings.check_fuel_reorg(); let core = settings.build_hyperlane_core(metrics.clone()); let contract_sync_metrics = Arc::new(ContractSyncMetrics::new(&metrics)); diff --git a/rust/main/chains/hyperlane-fuel/Cargo.toml b/rust/main/chains/hyperlane-fuel/Cargo.toml index da65af6686..9d5a9ff0ba 100644 --- a/rust/main/chains/hyperlane-fuel/Cargo.toml +++ b/rust/main/chains/hyperlane-fuel/Cargo.toml @@ -19,8 +19,14 @@ tracing.workspace = true hex.workspace = true url.workspace = true tokio.workspace = true +cynic.workspace = true +fuel-core-client.workspace = true +fuel-core-types.workspace = true +derive_more = { workspace = true, features = ["into", "from"] } +reqwest.workspace = true hyperlane-core = { path = "../../hyperlane-core", features = ["async"] } [build-dependencies] abigen = { path = "../../utils/abigen", features = ["fuels"] } +cynic-codegen = { workspace = true } diff --git a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json index 011fc1a0d6..38f1a37097 100644 --- a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json @@ -75,35 +75,40 @@ "concreteTypeId": "019ee4dbd8a5c577232b95d738e0bbcb2898c0417c9e0b05694284994582a199", "metadataTypeId": 12 }, + { + "type": "struct interfaces::mailbox::events::ProcessIdEvent", + "concreteTypeId": "e473e91ab8fc9b72d6833e3c5ffc45bff9a6da162b5dcec87a0fbd31858b6ee0", + "metadataTypeId": 13 + }, { "type": "struct interfaces::mailbox::events::RequiredHookSetEvent", "concreteTypeId": "be7aa440073b70d771ca9ed0e1520ed742cf67643ad38de897637be76a2fe6ea", - "metadataTypeId": 13 + "metadataTypeId": 14 }, { "type": "struct std::bytes::Bytes", "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 16 + "metadataTypeId": 17 }, { "type": "struct std::contract_id::ContractId", "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 18 + "metadataTypeId": 19 }, { "type": "struct sway_libs::ownership::events::OwnershipRenounced", "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", - "metadataTypeId": 19 + "metadataTypeId": 20 }, { "type": "struct sway_libs::ownership::events::OwnershipSet", "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", - "metadataTypeId": 20 + "metadataTypeId": 21 }, { "type": "struct sway_libs::ownership::events::OwnershipTransferred", "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", - "metadataTypeId": 21 + "metadataTypeId": 22 }, { "type": "u32", @@ -129,7 +134,7 @@ }, { "name": "InvalidProtocolVersion", - "typeId": 22 + "typeId": 23 }, { "name": "InvalidMessageOrigin", @@ -187,11 +192,11 @@ "components": [ { "name": "Address", - "typeId": 15 + "typeId": 16 }, { "name": "ContractId", - "typeId": 18 + "typeId": 19 } ] }, @@ -239,7 +244,7 @@ "components": [ { "name": "module", - "typeId": 18 + "typeId": 19 } ] }, @@ -249,7 +254,7 @@ "components": [ { "name": "module", - "typeId": 18 + "typeId": 19 } ] }, @@ -258,7 +263,7 @@ "metadataTypeId": 10, "components": [ { - "name": "message_id", + "name": "sender", "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { @@ -271,7 +276,7 @@ }, { "name": "message", - "typeId": 14 + "typeId": 15 } ] }, @@ -289,10 +294,6 @@ "type": "struct interfaces::mailbox::events::ProcessEvent", "metadataTypeId": 12, "components": [ - { - "name": "message_id", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - }, { "name": "origin", "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" @@ -308,28 +309,38 @@ ] }, { - "type": "struct interfaces::mailbox::events::RequiredHookSetEvent", + "type": "struct interfaces::mailbox::events::ProcessIdEvent", "metadataTypeId": 13, + "components": [ + { + "name": "message_id", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct interfaces::mailbox::events::RequiredHookSetEvent", + "metadataTypeId": 14, "components": [ { "name": "module", - "typeId": 18 + "typeId": 19 } ] }, { "type": "struct message::EncodedMessage", - "metadataTypeId": 14, + "metadataTypeId": 15, "components": [ { "name": "bytes", - "typeId": 16 + "typeId": 17 } ] }, { "type": "struct std::address::Address", - "metadataTypeId": 15, + "metadataTypeId": 16, "components": [ { "name": "bits", @@ -339,11 +350,11 @@ }, { "type": "struct std::bytes::Bytes", - "metadataTypeId": 16, + "metadataTypeId": 17, "components": [ { "name": "buf", - "typeId": 17 + "typeId": 18 }, { "name": "len", @@ -353,7 +364,7 @@ }, { "type": "struct std::bytes::RawBytes", - "metadataTypeId": 17, + "metadataTypeId": 18, "components": [ { "name": "ptr", @@ -367,7 +378,7 @@ }, { "type": "struct std::contract_id::ContractId", - "metadataTypeId": 18, + "metadataTypeId": 19, "components": [ { "name": "bits", @@ -377,7 +388,7 @@ }, { "type": "struct sway_libs::ownership::events::OwnershipRenounced", - "metadataTypeId": 19, + "metadataTypeId": 20, "components": [ { "name": "previous_owner", @@ -387,7 +398,7 @@ }, { "type": "struct sway_libs::ownership::events::OwnershipSet", - "metadataTypeId": 20, + "metadataTypeId": 21, "components": [ { "name": "new_owner", @@ -397,7 +408,7 @@ }, { "type": "struct sway_libs::ownership::events::OwnershipTransferred", - "metadataTypeId": 21, + "metadataTypeId": 22, "components": [ { "name": "new_owner", @@ -411,7 +422,7 @@ }, { "type": "u8", - "metadataTypeId": 22 + "metadataTypeId": 23 } ], "functions": [ @@ -917,12 +928,6 @@ "arguments": [ " * [u32] - The domain of the contract." ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] } ] }, @@ -1315,8 +1320,7 @@ { "name": "storage", "arguments": [ - "read", - "write" + "read" ] } ] @@ -1749,6 +1753,10 @@ "logId": "116782273241924983", "concreteTypeId": "019ee4dbd8a5c577232b95d738e0bbcb2898c0417c9e0b05694284994582a199" }, + { + "logId": "16461757363951278962", + "concreteTypeId": "e473e91ab8fc9b72d6833e3c5ffc45bff9a6da162b5dcec87a0fbd31858b6ee0" + }, { "logId": "4571204900286667806", "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" @@ -1779,7 +1787,7 @@ { "name": "LOCAL_DOMAIN", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 55856 + "offset": 56264 } ] } \ No newline at end of file diff --git a/rust/main/chains/hyperlane-fuel/build.rs b/rust/main/chains/hyperlane-fuel/build.rs index ba95d2b944..06fea24318 100644 --- a/rust/main/chains/hyperlane-fuel/build.rs +++ b/rust/main/chains/hyperlane-fuel/build.rs @@ -1,3 +1,9 @@ fn main() { abigen::generate_bindings_for_dir("./abis", "./src/contracts", abigen::BuildType::Fuels); + + cynic_codegen::register_schema("fuel") + .from_sdl_file("./src/indexer/query/schemas/fuel.graphql") + .unwrap() + .as_default() + .unwrap(); } diff --git a/rust/main/chains/hyperlane-fuel/src/indexer.rs b/rust/main/chains/hyperlane-fuel/src/indexer.rs deleted file mode 100644 index 05d49beed7..0000000000 --- a/rust/main/chains/hyperlane-fuel/src/indexer.rs +++ /dev/null @@ -1,297 +0,0 @@ -use crate::{conversions::*, indexer_events::FuelIndexerEvent, ConnectionConf, FuelProvider}; -use fuels::{ - accounts::wallet::WalletUnlocked, - client::{PageDirection, PaginationRequest}, - core::codec::LogDecoder, - types::{ - bech32::Bech32ContractId, - transaction::{Transaction, TransactionType}, - transaction_response::TransactionResponse, - tx_status::TxStatus, - BlockHeight, Bytes32, ContractId, - }, -}; -use hyperlane_core::{ - ChainCommunicationError, ChainResult, ContractLocator, Indexed, LogMeta, H512, U256, -}; -use std::{ - collections::HashMap, - fmt::Debug, - marker::PhantomData, - ops::{Deref, RangeInclusive}, -}; - -/// A Fuel Indexer supporting a specific event type. -/// The generic `E` is the type of the event this indexer will be filtering and parsing. -/// -/// # Fields -/// -/// * `fuel_provider` - An instance of `FuelProvider` responsible for interacting with the Fuel blockchain. -/// * `contract_address` - The Bech32 encoded contract ID that this indexer is associated with. -/// * `log_decoder` - An instance of `LogDecoder` used to decode logs emitted by the contract. -/// * `_phantom` - A marker to indicate the use of a generic type `E`. -pub struct FuelIndexer -where - E: FuelIndexerEvent, -{ - fuel_provider: FuelProvider, - contract_address: Bech32ContractId, - log_decoder: LogDecoder, - _phantom: PhantomData, -} - -impl Debug for FuelIndexer -where - E: FuelIndexerEvent, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("FuelIndexer") - .field("fuel_provider", &self.fuel_provider) - .field("contract_address", &self.contract_address) - .field("log_decoder", &self.log_decoder) - .finish() - } -} - -impl FuelIndexer -where - E: FuelIndexerEvent, -{ - /// Create a new fuel indexer - pub async fn new( - conf: &ConnectionConf, - locator: ContractLocator<'_>, - wallet: WalletUnlocked, - ) -> Self { - let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; - let contract_address = Bech32ContractId::from_h256(&locator.address); - - let decoder = E::log_decoder(contract_address.clone(), wallet); - - Self { - fuel_provider, - contract_address, - log_decoder: decoder, - _phantom: PhantomData, - } - } - - /// Index logs which were specified during the construction of the indexer. - /// The `E` type is the event which is being indexed. - /// The `T` type is the data which we are transforming the event data into. - pub async fn index_logs_in_range( - &self, - range: RangeInclusive, - ) -> ChainResult, LogMeta)>> - where - T: Into> + PartialEq + Send + Sync + Debug + 'static + From, - { - let (block_cursor, transaction_cursor) = self.get_sync_cursors(&range).await?; - - let transaction_map = self - .get_block_data(range.clone(), block_cursor.clone()) - .await?; - - // By now we are sure that we either have no transactions or matching transactions - let filtered_transactions = self - .get_transaction_data(&transaction_map, transaction_cursor.clone()) - .await?; - - // Transaction data with event data transformed into the relevant indexed data - let complete_indexer_log_data = self.append_with_event_data::(filtered_transactions); - - let indexed_logs: Vec<(Indexed, LogMeta)> = complete_indexer_log_data - .into_iter() - .map(|(tx_id, tx, data, log_index)| { - let (block_hash, transaction_index) = transaction_map.get(&tx_id).unwrap(); - - let log_meta = LogMeta { - address: self.contract_address.clone().into_h256(), - block_number: *tx.block_height.unwrap_or_default().deref() as u64, - block_hash: block_hash.into_h256(), - transaction_id: H512::from(tx_id.into_h256()), - transaction_index: transaction_index.to_owned(), - log_index, - }; - - (data.into(), log_meta) - }) - .collect::>(); - - Ok(indexed_logs) - } - - /// Get the custom Fuel Provider - pub fn provider(&self) -> &FuelProvider { - &self.fuel_provider - } - - fn has_event(&self, tx_data: &TransactionResponse) -> bool { - let decoder = &self.log_decoder; - if let TxStatus::Success { receipts } = &tx_data.status { - if let Ok(decoded_logs) = decoder.decode_logs_with_type::(receipts) { - return !decoded_logs.is_empty(); - } - } - false - } - - fn append_with_event_data( - &self, - filtered_transactions: Vec<(Bytes32, TransactionResponse)>, - ) -> Vec<(Bytes32, TransactionResponse, T, U256)> - where - T: Into> + PartialEq + Send + Sync + Debug + 'static + From, - { - let decoder = &self.log_decoder; - // Iterate over the filtered transactions - filtered_transactions - .into_iter() - .filter_map(|(tx_id, tx_data)| { - // Get the receipts from each transaction - if let TxStatus::Success { receipts } = &tx_data.status { - // Get the log index and the receipt log data - for (log_index, receipt) in receipts.iter().enumerate() { - // If the receipt contains the relevant log, we save the log and index - if let Ok(decoded_logs) = - decoder.decode_logs_with_type::(&[receipt.clone()]) - { - if !decoded_logs.is_empty() && decoded_logs.len() == 1 { - // Transform the event data into data used for indexing - let relevant_event = decoded_logs[0].clone().transform::(); - let log_index = U256::from(log_index as u64); - return Some((tx_id, tx_data, relevant_event, log_index)); - } - } - } - } - None // Return None if no relevant event data was found - }) - .collect::>() - } - - /// Check if a transaction is from a contract - /// @note: Only works for checking script transactions - fn is_transaction_from_contract(&self, res: &TransactionResponse) -> bool { - if let TransactionType::Script(script_transaction) = &res.transaction { - if script_transaction.inputs().iter().any(|input| { - input - .contract_id() - .is_some_and(|id| id == &ContractId::from(&self.contract_address)) - }) { - return true; - } - } - false - } - - async fn get_transaction_data( - &self, - transaction_map: &HashMap, - cursor: Option, - ) -> ChainResult> { - let transaction_ids = transaction_map.keys().cloned().collect::>(); - let req = PaginationRequest { - cursor, - results: transaction_ids.len() as i32, - direction: PageDirection::Forward, - }; - - let transactions = self - .fuel_provider - .provider() - .get_transactions(req) - .await - .map_err(ChainCommunicationError::from_other)?; - - let mut transaction_data = Vec::new(); - for (tx_data, tx_id) in transactions.results.iter().zip(transaction_ids) { - transaction_data.push((tx_id, tx_data.clone())); - } - - let filtered_transactions = transaction_data - .into_iter() - .filter(|(_, tx_data)| { - self.is_transaction_from_contract(tx_data) && self.has_event(tx_data) - }) - .collect::>(); - - Ok(filtered_transactions) - } - - async fn get_block_data( - &self, - range: RangeInclusive, - cursor: Option, - ) -> ChainResult> { - let result_amount: u32 = range.end() - range.start(); - let req = PaginationRequest { - cursor, - results: result_amount as i32, - direction: PageDirection::Forward, - }; - - let blocks = self - .fuel_provider - .provider() - .get_blocks(req) - .await - .map_err(ChainCommunicationError::from_other)?; - - let mut transaction_map: HashMap = HashMap::new(); - blocks.results.into_iter().for_each(|block| { - block - .transactions - .into_iter() - .enumerate() - .for_each(|(index, tx)| { - transaction_map.insert(tx, (block.id, index as u64)); - }); - }); - - Ok(transaction_map) - } - - async fn get_sync_cursors( - &self, - range: &RangeInclusive, - ) -> ChainResult<(Option, Option)> { - let range_start = range.start(); - if *range_start == 0 { - return Ok((None, None)); - } - - let start_block = BlockHeight::from(*range_start); - let block_data = match self - .fuel_provider - .provider() - .block_by_height(start_block) - .await - .map_err(ChainCommunicationError::from_other)? - { - Some(block) => block, - None => { - return Err(ChainCommunicationError::from_other_str( - "Block not found while building cursors", - )) - } - }; - - let first_transaction = match block_data.transactions.first() { - Some(tx) => tx, - None => { - return Err(ChainCommunicationError::from_other_str( - "Failed to get first transaction in block while building cursors", - )) - } - }; - - let hex_block = hex::encode(range_start.to_be_bytes()); - let hex_tx = hex::encode(first_transaction); - - let tx_cursor = Some(format!("{}#0x{}", hex_block, hex_tx)); - let block_cursor = Some(range_start.to_string()); - - Ok((block_cursor, tx_cursor)) - } -} diff --git a/rust/main/chains/hyperlane-fuel/src/indexer_events.rs b/rust/main/chains/hyperlane-fuel/src/indexer/events.rs similarity index 80% rename from rust/main/chains/hyperlane-fuel/src/indexer_events.rs rename to rust/main/chains/hyperlane-fuel/src/indexer/events.rs index 13e2863927..87fa417fb7 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer_events.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer/events.rs @@ -1,11 +1,5 @@ -use crate::{ - contracts::{ - interchain_gas_paymaster::{GasPaymentEvent, InterchainGasPaymaster as FuelIgpContract}, - mailbox::{DispatchEvent, Mailbox as FuelMailboxContract}, - merkle_tree_hook::{InsertedIntoTreeEvent, MerkleTreeHook as FuelMerkleTreeHookContract}, - }, - conversions::*, -}; +use std::fmt::Debug; + use fuels::{ accounts::wallet::WalletUnlocked, core::{ @@ -15,8 +9,19 @@ use fuels::{ programs::calls::ContractDependency, types::bech32::Bech32ContractId, }; -use hyperlane_core::{HyperlaneMessage, Indexed, InterchainGasPayment, MerkleTreeInsertion, U256}; -use std::fmt::Debug; + +use hyperlane_core::{ + Delivery, HyperlaneMessage, Indexed, InterchainGasPayment, MerkleTreeInsertion, U256, +}; + +use crate::{ + contracts::{ + interchain_gas_paymaster::{GasPaymentEvent, InterchainGasPaymaster as FuelIgpContract}, + mailbox::{DispatchEvent, Mailbox as FuelMailboxContract, ProcessIdEvent}, + merkle_tree_hook::{InsertedIntoTreeEvent, MerkleTreeHook as FuelMerkleTreeHookContract}, + }, + conversions::*, +}; /// Trait combination for Events which are supported by the Fuel Indexer pub trait FuelIndexerEvent: @@ -55,8 +60,15 @@ impl From for MerkleTreeInsertion { } } +impl From for Delivery { + fn from(event: ProcessIdEvent) -> Self { + event.message_id.into_h256() + } +} + /// Trait to transform events into indexable data types. pub trait EventDataTransformer { + /// Transform Fuel events into a specific type fn transform(self) -> T where T: From + Into> + PartialEq + Send + Sync + Debug + 'static, @@ -93,6 +105,16 @@ impl EventDataTransformer for InsertedIntoTreeEvent { } } +// Implement `EventDataTransformer` for `ProcessIdEvent` +impl EventDataTransformer for ProcessIdEvent { + fn transform(self) -> T + where + T: From + Into> + PartialEq + Send + Sync + Debug + 'static, + { + T::from(self) + } +} + /// Trait for getting decoders from different contracts depending on the event type pub trait HasLogDecoder { /// Get the log decoder for a specific contract @@ -116,3 +138,9 @@ impl HasLogDecoder for InsertedIntoTreeEvent { FuelMerkleTreeHookContract::new(contract_address, wallet).log_decoder() } } + +impl HasLogDecoder for ProcessIdEvent { + fn log_decoder(contract_address: Bech32ContractId, wallet: WalletUnlocked) -> LogDecoder { + FuelMailboxContract::new(contract_address, wallet).log_decoder() + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/mod.rs b/rust/main/chains/hyperlane-fuel/src/indexer/mod.rs new file mode 100644 index 0000000000..085c8d9438 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer/mod.rs @@ -0,0 +1,178 @@ +use std::{fmt::Debug, marker::PhantomData, ops::RangeInclusive}; + +use fuels::{ + accounts::wallet::WalletUnlocked, + core::codec::LogDecoder, + tx::Receipt, + types::{bech32::Bech32ContractId, ContractId}, +}; + +use hyperlane_core::{ChainResult, ContractLocator, Indexed, LogMeta, H512, U256}; + +/// Fuel Indexer event +pub mod events; +use events::FuelIndexerEvent; + +/// Custom GraphQL query for Fuel Indexer +mod query; +use query::{ + types::{BlocksQuery, Transaction as SchemaTransaction}, + FuelGraphQLClient, +}; + +use crate::{conversions::*, ConnectionConf, FuelProvider}; + +/// A Fuel Indexer supporting a specific event type. +/// The generic `E` is the type of the event this indexer will be filtering and parsing. +/// +/// # Fields +/// +/// * `fuel_provider` - An instance of `FuelProvider` responsible for interacting with the Fuel blockchain. +/// * `contract_address` - The Bech32 encoded contract ID that this indexer is associated with. +/// * `log_decoder` - An instance of `LogDecoder` used to decode logs emitted by the contract. +/// * `graphql_client` - An instance of `FuelGraphQLClient` used to query the Fuel blockchain. +/// * `_phantom` - A marker to indicate the use of a generic type `E`. +pub struct FuelIndexer +where + E: FuelIndexerEvent, +{ + fuel_provider: FuelProvider, + contract_address: Bech32ContractId, + log_decoder: LogDecoder, + graphql_client: FuelGraphQLClient, + _phantom: PhantomData, +} + +impl Debug for FuelIndexer +where + E: FuelIndexerEvent, +{ + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("FuelIndexer") + .field("fuel_provider", &self.fuel_provider) + .field("contract_address", &self.contract_address) + .field("log_decoder", &self.log_decoder) + .finish() + } +} + +impl FuelIndexer +where + E: FuelIndexerEvent, +{ + /// Create a new fuel indexer + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + wallet: WalletUnlocked, + ) -> Self { + let fuel_provider = FuelProvider::new(locator.domain.clone(), conf).await; + let contract_address = Bech32ContractId::from_h256(&locator.address); + let graphql_client = FuelGraphQLClient::new(&conf.url); + let decoder = E::log_decoder(contract_address.clone(), wallet); + + Self { + fuel_provider, + contract_address, + log_decoder: decoder, + graphql_client, + _phantom: PhantomData, + } + } + + /// Get the custom Fuel Provider + pub fn provider(&self) -> &FuelProvider { + &self.fuel_provider + } + + /// Index logs which were specified during the construction of the indexer. + /// The `E` type is the event which is being indexed. + /// The `T` type is the data which we are transforming the event data into. + pub async fn index_logs_in_range( + &self, + range: RangeInclusive, + ) -> ChainResult, LogMeta)>> + where + T: Into> + PartialEq + Send + Sync + Debug + 'static + From, + { + let block_data = self.graphql_client.query_blocks_in_range(&range).await?; + + Ok(self.filter_and_parse_transactions::(block_data)) + } + + fn filter_and_parse_transactions(&self, data: BlocksQuery) -> Vec<(Indexed, LogMeta)> + where + T: Into> + PartialEq + Send + Sync + Debug + 'static + From, + { + data.blocks + .nodes + .into_iter() + .flat_map(|block| { + let block_number = block.header.height.0 as u64; + let block_hash = block.id.0 .0.into_h256(); + + block + .transactions + .into_iter() + .enumerate() + .filter_map(move |(index, tx)| { + if !tx.is_valid() + || !self.is_transaction_from_contract(&tx) + || !self.has_event(&tx) + { + return None; + } + + let receipts = tx.extract_receipts().unwrap_or_default(); + + let (relevant_event, log_index) = + self.extract_log::(receipts.clone())?; + + let log_meta = LogMeta { + address: self.contract_address.clone().into_h256(), + block_number, + block_hash, + transaction_id: H512::from(tx.id.0 .0.into_h256()), + transaction_index: index as u64, + log_index: U256::from(log_index), + }; + + Some((relevant_event.into(), log_meta)) + }) + }) + .collect::>() + } + + fn has_event(&self, tx: &SchemaTransaction) -> bool { + let decoder = &self.log_decoder; + let receipts = tx.extract_receipts().unwrap_or_default(); + if let Ok(decoded_logs) = decoder.decode_logs_with_type::(&receipts) { + return !decoded_logs.is_empty(); + } + false + } + + fn extract_log(&self, receipts: Vec) -> Option<(T, usize)> + where + T: Into> + PartialEq + Send + Sync + Debug + 'static + From, + { + let decoder = &self.log_decoder; + for (index, receipt) in receipts.into_iter().enumerate() { + if let Ok(decoded_logs) = decoder.decode_logs_with_type::(&[receipt]) { + if !decoded_logs.is_empty() && decoded_logs.len() == 1 { + return Some((decoded_logs[0].clone().transform::(), index)); + } + } + } + None + } + + fn is_transaction_from_contract(&self, tx: &SchemaTransaction) -> bool { + if let Some(inputs) = &tx.input_contracts { + return inputs + .iter() + .any(|input| input.0 .0 == ContractId::from(&self.contract_address)); + } + false + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs new file mode 100644 index 0000000000..da25b7cf3b --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs @@ -0,0 +1,334 @@ +use fuel_core_client::client::schema::ConversionError::{self, MissingField}; +use fuel_core_types::{ + fuel_asm::{Instruction, Word}, + fuel_tx::{PanicInstruction, PanicReason}, +}; +use fuels::tx::Receipt as FuelRecepit; + +use super::{types::Receipt, ReceiptType}; + +// These conversions are the `From` implementations for converting the `Receipt` schema from the Fuels Rust SDK +// since we cannot implement `From` for our custom Recipt schema on the `fuels::tx::Receipt` directly. + +pub fn generate_receipt(schema: Receipt) -> Result { + Ok(match schema.receipt_type { + ReceiptType::Call => FuelRecepit::Call { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + to: schema + .to + .ok_or_else(|| MissingField("to".to_string()))? + .into(), + amount: schema + .amount + .ok_or_else(|| MissingField("amount".to_string()))? + .into(), + asset_id: schema + .asset_id + .ok_or_else(|| MissingField("assetId".to_string()))? + .into(), + gas: schema + .gas + .ok_or_else(|| MissingField("gas".to_string()))? + .into(), + param1: schema + .param1 + .ok_or_else(|| MissingField("param1".to_string()))? + .into(), + param2: schema + .param2 + .ok_or_else(|| MissingField("param2".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::Return => FuelRecepit::Return { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + val: schema + .val + .ok_or_else(|| MissingField("val".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::ReturnData => FuelRecepit::ReturnData { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + ptr: schema + .ptr + .ok_or_else(|| MissingField("ptr".to_string()))? + .into(), + len: schema + .len + .ok_or_else(|| MissingField("len".to_string()))? + .into(), + digest: schema + .digest + .ok_or_else(|| MissingField("digest".to_string()))? + .into(), + data: Some( + schema + .data + .ok_or_else(|| MissingField("data".to_string()))? + .into(), + ), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::Panic => FuelRecepit::Panic { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + reason: { + let reason = schema + .reason + .ok_or_else(|| MissingField("reason".to_string()))?; + word_to_panic_instruction(reason.into()) + }, + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + contract_id: schema.contract_id.map(Into::into), + }, + ReceiptType::Revert => FuelRecepit::Revert { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + ra: schema + .ra + .ok_or_else(|| MissingField("ra".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::Log => FuelRecepit::Log { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + ra: schema + .ra + .ok_or_else(|| MissingField("ra".to_string()))? + .into(), + rb: schema + .rb + .ok_or_else(|| MissingField("rb".to_string()))? + .into(), + rc: schema + .rc + .ok_or_else(|| MissingField("rc".to_string()))? + .into(), + rd: schema + .rd + .ok_or_else(|| MissingField("rd".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::LogData => FuelRecepit::LogData { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + ra: schema + .ra + .ok_or_else(|| MissingField("ra".to_string()))? + .into(), + rb: schema + .rb + .ok_or_else(|| MissingField("rb".to_string()))? + .into(), + ptr: schema + .ptr + .ok_or_else(|| MissingField("ptr".to_string()))? + .into(), + len: schema + .len + .ok_or_else(|| MissingField("len".to_string()))? + .into(), + digest: schema + .digest + .ok_or_else(|| MissingField("digest".to_string()))? + .into(), + data: Some( + schema + .data + .ok_or_else(|| MissingField("data".to_string()))? + .into(), + ), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::Transfer => FuelRecepit::Transfer { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + to: schema + .to + .ok_or_else(|| MissingField("to".to_string()))? + .into(), + amount: schema + .amount + .ok_or_else(|| MissingField("amount".to_string()))? + .into(), + asset_id: schema + .asset_id + .ok_or_else(|| MissingField("assetId".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::TransferOut => FuelRecepit::TransferOut { + id: schema.id.map(|id| id.into()).unwrap_or_default(), + to: schema + .to_address + .ok_or_else(|| MissingField("to_address".to_string()))? + .into(), + amount: schema + .amount + .ok_or_else(|| MissingField("amount".to_string()))? + .into(), + asset_id: schema + .asset_id + .ok_or_else(|| MissingField("assetId".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::ScriptResult => FuelRecepit::ScriptResult { + result: Word::from( + schema + .result + .ok_or_else(|| MissingField("result".to_string()))?, + ) + .into(), + gas_used: schema + .gas_used + .ok_or_else(|| MissingField("gas_used".to_string()))? + .into(), + }, + ReceiptType::MessageOut => FuelRecepit::MessageOut { + sender: schema + .sender + .ok_or_else(|| MissingField("sender".to_string()))? + .into(), + recipient: schema + .recipient + .ok_or_else(|| MissingField("recipient".to_string()))? + .into(), + amount: schema + .amount + .ok_or_else(|| MissingField("amount".to_string()))? + .into(), + nonce: schema + .nonce + .ok_or_else(|| MissingField("nonce".to_string()))? + .into(), + len: schema + .len + .ok_or_else(|| MissingField("len".to_string()))? + .into(), + digest: schema + .digest + .ok_or_else(|| MissingField("digest".to_string()))? + .into(), + data: Some( + schema + .data + .ok_or_else(|| MissingField("data".to_string()))? + .into(), + ), + }, + ReceiptType::Mint => FuelRecepit::Mint { + sub_id: schema + .sub_id + .ok_or_else(|| MissingField("sub_id".to_string()))? + .into(), + contract_id: schema.id.map(|id| id.into()).unwrap_or_default(), + val: schema + .val + .ok_or_else(|| MissingField("val".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + ReceiptType::Burn => FuelRecepit::Burn { + sub_id: schema + .sub_id + .ok_or_else(|| MissingField("sub_id".to_string()))? + .into(), + contract_id: schema.id.map(|id| id.into()).unwrap_or_default(), + val: schema + .val + .ok_or_else(|| MissingField("val".to_string()))? + .into(), + pc: schema + .pc + .ok_or_else(|| MissingField("pc".to_string()))? + .into(), + is: schema + .is + .ok_or_else(|| MissingField("is".to_string()))? + .into(), + }, + }) +} + +const WORD_SIZE: usize = core::mem::size_of::(); +const REASON_OFFSET: Word = (WORD_SIZE * 8 - 8) as Word; +const INSTR_OFFSET: Word = REASON_OFFSET - (Instruction::SIZE * 8) as Word; + +#[allow(clippy::cast_possible_truncation)] +pub fn word_to_panic_instruction(val: Word) -> PanicInstruction { + // Safe to cast as we've shifted the 8 MSB. + let reason_u8 = (val >> REASON_OFFSET) as u8; + // Cast to truncate in order to remove the `reason` bits. + let instruction = (val >> INSTR_OFFSET) as u32; + let reason = PanicReason::from(reason_u8); + PanicInstruction::error(reason, instruction.into()) +} diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/mod.rs b/rust/main/chains/hyperlane-fuel/src/indexer/query/mod.rs new file mode 100644 index 0000000000..bea21df44f --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/mod.rs @@ -0,0 +1,98 @@ +use std::ops::RangeInclusive; + +use cynic::{GraphQlResponse, QueryBuilder}; +use fuels::client::{PageDirection, PaginationRequest}; +use reqwest::Client; +use tracing::warn; +use url::Url; + +use hyperlane_core::{ChainCommunicationError, ChainResult}; + +pub mod types; +use types::*; + +mod conversions; +use conversions::*; + +/// A GraphQL client for querying the Fuel blockchain. +/// It's used due to the limitations of the Fuels Rust SDK. +pub struct FuelGraphQLClient { + client: Client, + url: Url, +} + +impl FuelGraphQLClient { + /// Create a new FuelGraphQLClient + pub fn new(url: &Url) -> Self { + Self { + client: reqwest::Client::new(), + url: url.clone(), + } + } + + /// Query blocks in a specific range + pub async fn query_blocks_in_range( + &self, + range: &RangeInclusive, + ) -> ChainResult { + let request = self.build_request(range); + let operation: cynic::Operation = + BlocksQuery::build(request.into()); + + let response = self + .client + .post(self.url.clone()) + .json(&operation) + .send() + .await + .map_err(ChainCommunicationError::from_other)?; + + let parsed_response = response + .json::>() + .await + .map_err(ChainCommunicationError::from_other)?; + + self.handle_response(parsed_response) + } + + /// Convert a range into a FuelVM pagination request + fn build_request(&self, range: &RangeInclusive) -> PaginationRequest { + let range_start = range.start(); + let result_amount: u32 = range.end() - range.start(); + if *range_start == 0 { + return PaginationRequest { + cursor: None, + results: result_amount as i32, + direction: PageDirection::Forward, + }; + } + + PaginationRequest { + cursor: Some(range_start.to_string()), + results: result_amount as i32, + direction: PageDirection::Forward, + } + } + + /// Handle the response from the FuelVM GraphQL query + fn handle_response(&self, response: GraphQlResponse) -> ChainResult { + if let Some(errors) = &response.errors { + if response.data.is_none() { + return Err(ChainCommunicationError::from_other_str( + format!("Error executing custom FuelVM GraphQL query: {:?}", errors).as_str(), + )); + } + + for error in errors { + warn!("Error executing custom FuelVM GraphQL query {:?}", error); + } + } + + match response.data { + Some(data) => Ok(data), + None => Err(ChainCommunicationError::from_other_str( + "No data received from FuelVM GraphQL query", + )), + } + } +} diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/schemas/fuel.graphql b/rust/main/chains/hyperlane-fuel/src/indexer/query/schemas/fuel.graphql new file mode 100644 index 0000000000..eb57d3d1c0 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/schemas/fuel.graphql @@ -0,0 +1,1298 @@ +scalar Address + +scalar AssetId + +type Balance { + owner: Address! + amount: U64! + assetId: AssetId! +} + +type BalanceConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [BalanceEdge!]! + """ + A list of nodes. + """ + nodes: [Balance!]! +} + +""" +An edge in a connection. +""" +type BalanceEdge { + """ + The item at the end of the edge + """ + node: Balance! + """ + A cursor for use in pagination + """ + cursor: String! +} + +input BalanceFilterInput { + """ + Filter coins based on the `owner` field + """ + owner: Address! +} + +type Blob { + id: BlobId! + bytecode: HexString! +} + +scalar BlobId + +type Block { + version: BlockVersion! + id: BlockId! + height: U32! + header: Header! + consensus: Consensus! + transactionIds: [TransactionId!]! + transactions: [Transaction!]! +} + +type BlockConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [BlockEdge!]! + """ + A list of nodes. + """ + nodes: [Block!]! +} + +""" +An edge in a connection. +""" +type BlockEdge { + """ + The item at the end of the edge + """ + node: Block! + """ + A cursor for use in pagination + """ + cursor: String! +} + +scalar BlockId + +enum BlockVersion { + V1 +} + +""" +Breakpoint, defined as a tuple of contract ID and relative PC offset inside it +""" +input Breakpoint { + contract: ContractId! + pc: U64! +} + +scalar Bytes32 + +type ChainInfo { + name: String! + latestBlock: Block! + daHeight: U64! + consensusParameters: ConsensusParameters! + gasCosts: GasCosts! +} + +type ChangeOutput { + to: Address! + amount: U64! + assetId: AssetId! +} + +type Coin { + utxoId: UtxoId! + owner: Address! + amount: U64! + assetId: AssetId! + """ + TxPointer - the height of the block this coin was created in + """ + blockCreated: U32! + """ + TxPointer - the index of the transaction that created this coin + """ + txCreatedIdx: U16! +} + +type CoinConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [CoinEdge!]! + """ + A list of nodes. + """ + nodes: [Coin!]! +} + +""" +An edge in a connection. +""" +type CoinEdge { + """ + The item at the end of the edge + """ + node: Coin! + """ + A cursor for use in pagination + """ + cursor: String! +} + +input CoinFilterInput { + """ + Returns coins owned by the `owner`. + """ + owner: Address! + """ + Returns coins only with `asset_id`. + """ + assetId: AssetId +} + +type CoinOutput { + to: Address! + amount: U64! + assetId: AssetId! +} + +""" +The schema analog of the [`coins::CoinType`]. +""" +union CoinType = Coin | MessageCoin + +union Consensus = Genesis | PoAConsensus + +type ConsensusParameters { + version: ConsensusParametersVersion! + txParams: TxParameters! + predicateParams: PredicateParameters! + scriptParams: ScriptParameters! + contractParams: ContractParameters! + feeParams: FeeParameters! + baseAssetId: AssetId! + blockGasLimit: U64! + blockTransactionSizeLimit: U64! + chainId: U64! + gasCosts: GasCosts! + privilegedAddress: Address! +} + +type ConsensusParametersPurpose { + witnessIndex: U16! + checksum: Bytes32! +} + +enum ConsensusParametersVersion { + V1 +} + +type Contract { + id: ContractId! + bytecode: HexString! + salt: Salt! +} + +type ContractBalance { + contract: ContractId! + amount: U64! + assetId: AssetId! +} + +type ContractBalanceConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [ContractBalanceEdge!]! + """ + A list of nodes. + """ + nodes: [ContractBalance!]! +} + +""" +An edge in a connection. +""" +type ContractBalanceEdge { + """ + The item at the end of the edge + """ + node: ContractBalance! + """ + A cursor for use in pagination + """ + cursor: String! +} + +input ContractBalanceFilterInput { + """ + Filter assets based on the `contractId` field + """ + contract: ContractId! +} + +type ContractCreated { + contract: ContractId! + stateRoot: Bytes32! +} + +scalar ContractId + +type ContractOutput { + inputIndex: U16! + balanceRoot: Bytes32! + stateRoot: Bytes32! +} + +type ContractParameters { + version: ContractParametersVersion! + contractMaxSize: U64! + maxStorageSlots: U64! +} + +enum ContractParametersVersion { + V1 +} + +type DaCompressedBlock { + bytes: HexString! +} + +union DependentCost = LightOperation | HeavyOperation + +type DryRunFailureStatus { + programState: ProgramState + reason: String! + receipts: [Receipt!]! + totalGas: U64! + totalFee: U64! +} + +type DryRunSuccessStatus { + programState: ProgramState + receipts: [Receipt!]! + totalGas: U64! + totalFee: U64! +} + +type DryRunTransactionExecutionStatus { + id: TransactionId! + status: DryRunTransactionStatus! + receipts: [Receipt!]! +} + +union DryRunTransactionStatus = DryRunSuccessStatus | DryRunFailureStatus + +type EstimateGasPrice { + gasPrice: U64! +} + +input ExcludeInput { + """ + Utxos to exclude from the selection. + """ + utxos: [UtxoId!]! + """ + Messages to exclude from the selection. + """ + messages: [Nonce!]! +} + +type FailureStatus { + transactionId: TransactionId! + blockHeight: U32! + block: Block! + transaction: Transaction! + time: Tai64Timestamp! + reason: String! + programState: ProgramState + receipts: [Receipt!]! + totalGas: U64! + totalFee: U64! +} + +type FeeParameters { + version: FeeParametersVersion! + gasPriceFactor: U64! + gasPerByte: U64! +} + +enum FeeParametersVersion { + V1 +} + +type GasCosts { + version: GasCostsVersion! + add: U64! + addi: U64! + aloc: U64! + and: U64! + andi: U64! + bal: U64! + bhei: U64! + bhsh: U64! + burn: U64! + cb: U64! + cfei: U64! + cfsi: U64! + div: U64! + divi: U64! + ecr1: U64! + eck1: U64! + ed19: U64! + eq: U64! + exp: U64! + expi: U64! + flag: U64! + gm: U64! + gt: U64! + gtf: U64! + ji: U64! + jmp: U64! + jne: U64! + jnei: U64! + jnzi: U64! + jmpf: U64! + jmpb: U64! + jnzf: U64! + jnzb: U64! + jnef: U64! + jneb: U64! + lb: U64! + log: U64! + lt: U64! + lw: U64! + mint: U64! + mlog: U64! + modOp: U64! + modi: U64! + moveOp: U64! + movi: U64! + mroo: U64! + mul: U64! + muli: U64! + mldv: U64! + noop: U64! + not: U64! + or: U64! + ori: U64! + poph: U64! + popl: U64! + pshh: U64! + pshl: U64! + ret: U64! + rvrt: U64! + sb: U64! + sll: U64! + slli: U64! + srl: U64! + srli: U64! + srw: U64! + sub: U64! + subi: U64! + sw: U64! + sww: U64! + time: U64! + tr: U64! + tro: U64! + wdcm: U64! + wqcm: U64! + wdop: U64! + wqop: U64! + wdml: U64! + wqml: U64! + wddv: U64! + wqdv: U64! + wdmd: U64! + wqmd: U64! + wdam: U64! + wqam: U64! + wdmm: U64! + wqmm: U64! + xor: U64! + xori: U64! + alocDependentCost: DependentCost! + bldd: DependentCost + bsiz: DependentCost + cfe: DependentCost! + cfeiDependentCost: DependentCost! + call: DependentCost! + ccp: DependentCost! + croo: DependentCost! + csiz: DependentCost! + ed19DependentCost: DependentCost! + k256: DependentCost! + ldc: DependentCost! + logd: DependentCost! + mcl: DependentCost! + mcli: DependentCost! + mcp: DependentCost! + mcpi: DependentCost! + meq: DependentCost! + retd: DependentCost! + s256: DependentCost! + scwq: DependentCost! + smo: DependentCost! + srwq: DependentCost! + swwq: DependentCost! + contractRoot: DependentCost! + stateRoot: DependentCost! + vmInitialization: DependentCost! + newStoragePerByte: U64! +} + +enum GasCostsVersion { + V1 +} + +type Genesis { + """ + The chain configs define what consensus type to use, what settlement layer to use, + rules of block validity, etc. + """ + chainConfigHash: Bytes32! + """ + The Binary Merkle Tree root of all genesis coins. + """ + coinsRoot: Bytes32! + """ + The Binary Merkle Tree root of state, balances, contracts code hash of each contract. + """ + contractsRoot: Bytes32! + """ + The Binary Merkle Tree root of all genesis messages. + """ + messagesRoot: Bytes32! + """ + The Binary Merkle Tree root of all processed transaction ids. + """ + transactionsRoot: Bytes32! +} + +type Header { + """ + Version of the header + """ + version: HeaderVersion! + """ + Hash of the header + """ + id: BlockId! + """ + The layer 1 height of messages and events to include since the last layer 1 block number. + """ + daHeight: U64! + """ + The version of the consensus parameters used to create this block. + """ + consensusParametersVersion: U32! + """ + The version of the state transition bytecode used to create this block. + """ + stateTransitionBytecodeVersion: U32! + """ + Number of transactions in this block. + """ + transactionsCount: U16! + """ + Number of message receipts in this block. + """ + messageReceiptCount: U32! + """ + Merkle root of transactions. + """ + transactionsRoot: Bytes32! + """ + Merkle root of message receipts in this block. + """ + messageOutboxRoot: Bytes32! + """ + Merkle root of inbox events in this block. + """ + eventInboxRoot: Bytes32! + """ + Fuel block height. + """ + height: U32! + """ + Merkle root of all previous block header hashes. + """ + prevRoot: Bytes32! + """ + The block producer time. + """ + time: Tai64Timestamp! + """ + Hash of the application header. + """ + applicationHash: Bytes32! +} + +enum HeaderVersion { + V1 +} + +type HeavyOperation { + base: U64! + gasPerUnit: U64! +} + +scalar HexString + +union Input = InputCoin | InputContract | InputMessage + +type InputCoin { + utxoId: UtxoId! + owner: Address! + amount: U64! + assetId: AssetId! + txPointer: TxPointer! + witnessIndex: Int! + predicateGasUsed: U64! + predicate: HexString! + predicateData: HexString! +} + +type InputContract { + utxoId: UtxoId! + balanceRoot: Bytes32! + stateRoot: Bytes32! + txPointer: TxPointer! + contractId: ContractId! +} + +type InputMessage { + sender: Address! + recipient: Address! + amount: U64! + nonce: Nonce! + witnessIndex: U16! + predicateGasUsed: U64! + data: HexString! + predicate: HexString! + predicateData: HexString! +} + +type LatestGasPrice { + gasPrice: U64! + blockHeight: U32! +} + +type LightOperation { + base: U64! + unitsPerGas: U64! +} + +type MerkleProof { + proofSet: [Bytes32!]! + proofIndex: U64! +} + +type Message { + amount: U64! + sender: Address! + recipient: Address! + nonce: Nonce! + data: HexString! + daHeight: U64! +} + +type MessageCoin { + sender: Address! + recipient: Address! + nonce: Nonce! + amount: U64! + assetId: AssetId! + daHeight: U64! +} + +type MessageConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [MessageEdge!]! + """ + A list of nodes. + """ + nodes: [Message!]! +} + +""" +An edge in a connection. +""" +type MessageEdge { + """ + The item at the end of the edge + """ + node: Message! + """ + A cursor for use in pagination + """ + cursor: String! +} + +type MessageProof { + messageProof: MerkleProof! + blockProof: MerkleProof! + messageBlockHeader: Header! + commitBlockHeader: Header! + sender: Address! + recipient: Address! + nonce: Nonce! + amount: U64! + data: HexString! +} + +enum MessageState { + UNSPENT + SPENT + NOT_FOUND +} + +type MessageStatus { + state: MessageState! +} + +type Mutation { + """ + Initialize a new debugger session, returning its ID. + A new VM instance is spawned for each session. + The session is run in a separate database transaction, + on top of the most recent node state. + """ + startSession: ID! + """ + End debugger session. + """ + endSession(id: ID!): Boolean! + """ + Reset the VM instance to the initial state. + """ + reset(id: ID!): Boolean! + """ + Execute a single fuel-asm instruction. + """ + execute(id: ID!, op: String!): Boolean! + """ + Set single-stepping mode for the VM instance. + """ + setSingleStepping(id: ID!, enable: Boolean!): Boolean! + """ + Set a breakpoint for a VM instance. + """ + setBreakpoint(id: ID!, breakpoint: Breakpoint!): Boolean! + """ + Run a single transaction in given session until it + hits a breakpoint or completes. + """ + startTx(id: ID!, txJson: String!): RunResult! + """ + Resume execution of the VM instance after a breakpoint. + Runs until the next breakpoint or until the transaction completes. + """ + continueTx(id: ID!): RunResult! + """ + Execute a dry-run of multiple transactions using a fork of current state, no changes are committed. + """ + dryRun(txs: [HexString!]!, utxoValidation: Boolean, gasPrice: U64): [DryRunTransactionExecutionStatus!]! + """ + Submits transaction to the `TxPool`. + + Returns submitted transaction if the transaction is included in the `TxPool` without problems. + """ + submit(tx: HexString!): Transaction! + """ + Sequentially produces `blocks_to_produce` blocks. The first block starts with + `start_timestamp`. If the block production in the [`crate::service::Config`] is + `Trigger::Interval { block_time }`, produces blocks with `block_time ` intervals between + them. The `start_timestamp` is the timestamp in seconds. + """ + produceBlocks(startTimestamp: Tai64Timestamp, blocksToProduce: U32!): U32! +} + +type NodeInfo { + utxoValidation: Boolean! + vmBacktrace: Boolean! + maxTx: U64! + maxDepth: U64! + nodeVersion: String! + peers: [PeerInfo!]! +} + +scalar Nonce + +union Output = CoinOutput | ContractOutput | ChangeOutput | VariableOutput | ContractCreated + +""" +A separate `Breakpoint` type to be used as an output, as a single +type cannot act as both input and output type in async-graphql +""" +type OutputBreakpoint { + contract: ContractId! + pc: U64! +} + +""" +Information about pagination in a connection +""" +type PageInfo { + """ + When paginating backwards, are there more items? + """ + hasPreviousPage: Boolean! + """ + When paginating forwards, are there more items? + """ + hasNextPage: Boolean! + """ + When paginating backwards, the cursor to continue. + """ + startCursor: String + """ + When paginating forwards, the cursor to continue. + """ + endCursor: String +} + +type PeerInfo { + """ + The libp2p peer id + """ + id: String! + """ + The advertised multi-addrs that can be used to connect to this peer + """ + addresses: [String!]! + """ + The self-reported version of the client the peer is using + """ + clientVersion: String + """ + The last reported height of the peer + """ + blockHeight: U32 + """ + The last heartbeat from this peer in unix epoch time ms + """ + lastHeartbeatMs: U64! + """ + The internal fuel p2p reputation of this peer + """ + appScore: Float! +} + +type PoAConsensus { + """ + Gets the signature of the block produced by `PoA` consensus. + """ + signature: Signature! +} + +type Policies { + tip: U64 + witnessLimit: U64 + maturity: U32 + maxFee: U64 +} + +type PredicateParameters { + version: PredicateParametersVersion! + maxPredicateLength: U64! + maxPredicateDataLength: U64! + maxGasPerPredicate: U64! + maxMessageDataLength: U64! +} + +enum PredicateParametersVersion { + V1 +} + +type ProgramState { + returnType: ReturnType! + data: HexString! +} + +type Query { + """ + Read register value by index. + """ + register(id: ID!, register: U32!): U64! + """ + Read read a range of memory bytes. + """ + memory(id: ID!, start: U32!, size: U32!): String! + balance( + """ + address of the owner + """ + owner: Address! + """ + asset_id of the coin + """ + assetId: AssetId! + ): Balance! + balances(filter: BalanceFilterInput!, first: Int, after: String, last: Int, before: String): BalanceConnection! + blob( + """ + ID of the Blob + """ + id: BlobId! + ): Blob + block( + """ + ID of the block + """ + id: BlockId + """ + Height of the block + """ + height: U32 + ): Block + blocks(first: Int, after: String, last: Int, before: String): BlockConnection! + chain: ChainInfo! + transaction( + """ + The ID of the transaction + """ + id: TransactionId! + ): Transaction + transactions(first: Int, after: String, last: Int, before: String): TransactionConnection! + transactionsByOwner(owner: Address!, first: Int, after: String, last: Int, before: String): TransactionConnection! + """ + Estimate the predicate gas for the provided transaction + """ + estimatePredicates(tx: HexString!): Transaction! + """ + Returns true when the GraphQL API is serving requests. + """ + health: Boolean! + """ + Gets the coin by `utxo_id`. + """ + coin( + """ + The ID of the coin + """ + utxoId: UtxoId! + ): Coin + """ + Gets all unspent coins of some `owner` maybe filtered with by `asset_id` per page. + """ + coins(filter: CoinFilterInput!, first: Int, after: String, last: Int, before: String): CoinConnection! + """ + For each `query_per_asset`, get some spendable coins(of asset specified by the query) owned by + `owner` that add up at least the query amount. The returned coins can be spent. + The number of coins is optimized to prevent dust accumulation. + + The query supports excluding and maximum the number of coins. + + Returns: + The list of spendable coins per asset from the query. The length of the result is + the same as the length of `query_per_asset`. The ordering of assets and `query_per_asset` + is the same. + """ + coinsToSpend( + """ + The `Address` of the coins owner. + """ + owner: Address! + """ + The list of requested assets` coins with asset ids, `target` amount the user wants to reach, and the `max` number of coins in the selection. Several entries with the same asset id are not allowed. The result can't contain more coins than `max_inputs`. + """ + queryPerAsset: [SpendQueryElementInput!]! + """ + The excluded coins from the selection. + """ + excludedIds: ExcludeInput + ): [[CoinType!]!]! + daCompressedBlock( + """ + Height of the block + """ + height: U32! + ): DaCompressedBlock + contract( + """ + ID of the Contract + """ + id: ContractId! + ): Contract + contractBalance(contract: ContractId!, asset: AssetId!): ContractBalance! + contractBalances( + filter: ContractBalanceFilterInput! + first: Int + after: String + last: Int + before: String + ): ContractBalanceConnection! + nodeInfo: NodeInfo! + latestGasPrice: LatestGasPrice! + estimateGasPrice( + """ + Number of blocks into the future to estimate the gas price for + """ + blockHorizon: U32 + ): EstimateGasPrice! + message( + """ + The Nonce of the message + """ + nonce: Nonce! + ): Message + messages( + """ + address of the owner + """ + owner: Address + first: Int + after: String + last: Int + before: String + ): MessageConnection! + messageProof( + transactionId: TransactionId! + nonce: Nonce! + commitBlockId: BlockId + commitBlockHeight: U32 + ): MessageProof + messageStatus(nonce: Nonce!): MessageStatus! + relayedTransactionStatus( + """ + The id of the relayed tx + """ + id: RelayedTransactionId! + ): RelayedTransactionStatus + consensusParameters(version: Int!): ConsensusParameters! + stateTransitionBytecodeByVersion(version: Int!): StateTransitionBytecode + stateTransitionBytecodeByRoot(root: HexString!): StateTransitionBytecode! +} + +type Receipt { + id: ContractId + pc: U64 + is: U64 + to: ContractId + toAddress: Address + amount: U64 + assetId: AssetId + gas: U64 + param1: U64 + param2: U64 + val: U64 + ptr: U64 + digest: Bytes32 + reason: U64 + ra: U64 + rb: U64 + rc: U64 + rd: U64 + len: U64 + receiptType: ReceiptType! + result: U64 + gasUsed: U64 + data: HexString + sender: Address + recipient: Address + nonce: Nonce + """ + Set in the case of a Panic receipt to indicate a missing contract input id + """ + contractId: ContractId + subId: Bytes32 +} + +enum ReceiptType { + CALL + RETURN + RETURN_DATA + PANIC + REVERT + LOG + LOG_DATA + TRANSFER + TRANSFER_OUT + SCRIPT_RESULT + MESSAGE_OUT + MINT + BURN +} + +type RelayedTransactionFailed { + blockHeight: U32! + failure: String! +} + +scalar RelayedTransactionId + +union RelayedTransactionStatus = RelayedTransactionFailed + +enum ReturnType { + RETURN + RETURN_DATA + REVERT +} + +type RunResult { + state: RunState! + breakpoint: OutputBreakpoint + jsonReceipts: [String!]! +} + +enum RunState { + """ + All breakpoints have been processed, and the program has terminated + """ + COMPLETED + """ + Stopped on a breakpoint + """ + BREAKPOINT +} + +scalar Salt + +type ScriptParameters { + version: ScriptParametersVersion! + maxScriptLength: U64! + maxScriptDataLength: U64! +} + +enum ScriptParametersVersion { + V1 +} + +scalar Signature + +input SpendQueryElementInput { + """ + Identifier of the asset to spend. + """ + assetId: AssetId! + """ + Target amount for the query. + """ + amount: U64! + """ + The maximum number of currencies for selection. + """ + max: U32 +} + +type SqueezedOutStatus { + reason: String! +} + +type StateTransitionBytecode { + root: HexString! + bytecode: UploadedBytecode! +} + +type StateTransitionPurpose { + root: Bytes32! +} + +type SubmittedStatus { + time: Tai64Timestamp! +} + +type Subscription { + """ + Returns a stream of status updates for the given transaction id. + If the current status is [`TransactionStatus::Success`], [`TransactionStatus::SqueezedOut`] + or [`TransactionStatus::Failed`] the stream will return that and end immediately. + If the current status is [`TransactionStatus::Submitted`] this will be returned + and the stream will wait for a future update. + + This stream will wait forever so it's advised to use within a timeout. + + It is possible for the stream to miss an update if it is polled slower + then the updates arrive. In such a case the stream will close without + a status. If this occurs the stream can simply be restarted to return + the latest status. + """ + statusChange( + """ + The ID of the transaction + """ + id: TransactionId! + ): TransactionStatus! + """ + Submits transaction to the `TxPool` and await either confirmation or failure. + """ + submitAndAwait(tx: HexString!): TransactionStatus! + """ + Submits the transaction to the `TxPool` and returns a stream of events. + Compared to the `submitAndAwait`, the stream also contains ` + SubmittedStatus` as an intermediate state. + """ + submitAndAwaitStatus(tx: HexString!): TransactionStatus! +} + +type SuccessStatus { + transactionId: TransactionId! + blockHeight: U32! + block: Block! + transaction: Transaction! + time: Tai64Timestamp! + programState: ProgramState + receipts: [Receipt!]! + totalGas: U64! + totalFee: U64! +} + +scalar Tai64Timestamp + +type Transaction { + id: TransactionId! + inputAssetIds: [AssetId!] + inputContracts: [ContractId!] + inputContract: InputContract + policies: Policies + scriptGasLimit: U64 + maturity: U32 + mintAmount: U64 + mintAssetId: AssetId + mintGasPrice: U64 + txPointer: TxPointer + isScript: Boolean! + isCreate: Boolean! + isMint: Boolean! + isUpgrade: Boolean! + isUpload: Boolean! + isBlob: Boolean! + inputs: [Input!] + outputs: [Output!]! + outputContract: ContractOutput + witnesses: [HexString!] + receiptsRoot: Bytes32 + status: TransactionStatus + script: HexString + scriptData: HexString + bytecodeWitnessIndex: U16 + blobId: BlobId + salt: Salt + storageSlots: [HexString!] + bytecodeRoot: Bytes32 + subsectionIndex: U16 + subsectionsNumber: U16 + proofSet: [Bytes32!] + upgradePurpose: UpgradePurpose + """ + Return the transaction bytes using canonical encoding + """ + rawPayload: HexString! +} + +type TransactionConnection { + """ + Information to aid in pagination. + """ + pageInfo: PageInfo! + """ + A list of edges. + """ + edges: [TransactionEdge!]! + """ + A list of nodes. + """ + nodes: [Transaction!]! +} + +""" +An edge in a connection. +""" +type TransactionEdge { + """ + The item at the end of the edge + """ + node: Transaction! + """ + A cursor for use in pagination + """ + cursor: String! +} + +scalar TransactionId + +union TransactionStatus = SubmittedStatus | SuccessStatus | SqueezedOutStatus | FailureStatus + +type TxParameters { + version: TxParametersVersion! + maxInputs: U16! + maxOutputs: U16! + maxWitnesses: U32! + maxGasPerTx: U64! + maxSize: U64! + maxBytecodeSubsections: U16! +} + +enum TxParametersVersion { + V1 +} + +scalar TxPointer + +scalar U16 + +scalar U32 + +scalar U64 + +union UpgradePurpose = ConsensusParametersPurpose | StateTransitionPurpose + +type UploadedBytecode { + """ + Combined bytecode of all uploaded subsections. + """ + bytecode: HexString! + """ + Number of uploaded subsections (if incomplete). + """ + uploadedSubsectionsNumber: Int + """ + Indicates if the bytecode upload is complete. + """ + completed: Boolean! +} + +scalar UtxoId + +type VariableOutput { + to: Address! + amount: U64! + assetId: AssetId! +} + diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/types.rs b/rust/main/chains/hyperlane-fuel/src/indexer/query/types.rs new file mode 100644 index 0000000000..5898530c89 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/types.rs @@ -0,0 +1,257 @@ +use std::{fmt::Display, fmt::Formatter, str::FromStr}; + +use cynic::impl_scalar; +use fuel_core_client::client::schema::{ + primitives::{HexFormatted, HexString, Tai64Timestamp}, + ConversionError, +}; +use fuels::{ + client::{PageDirection, PaginationRequest}, + tx::Receipt as FuelReceipt, +}; +use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer}; + +use super::generate_receipt; + +#[cynic::schema("fuel")] +mod schema {} + +// The following macros and conversions are copied from the Fuels Rust SDK +// This allows us to customize the GraphQL schema types and request different +// parameters based on the needs of the Hyperlane Fuel Indexer + +macro_rules! fuel_type_scalar { + ($id:ident, $ft_id:ident) => { + #[derive(cynic::Scalar, Debug, Clone, Default)] + pub struct $id(pub HexFormatted<::fuel_core_types::fuel_types::$ft_id>); + + impl FromStr for $id { + type Err = ConversionError; + + fn from_str(s: &str) -> Result { + let b = HexFormatted::<::fuel_core_types::fuel_types::$ft_id>::from_str(s)?; + Ok($id(b)) + } + } + + impl From<$id> for ::fuel_core_types::fuel_types::$ft_id { + fn from(s: $id) -> Self { + ::fuel_core_types::fuel_types::$ft_id::new(s.0 .0.into()) + } + } + + impl From<::fuel_core_types::fuel_types::$ft_id> for $id { + fn from(s: ::fuel_core_types::fuel_types::$ft_id) -> Self { + $id(HexFormatted::<::fuel_core_types::fuel_types::$ft_id>(s)) + } + } + + impl Display for $id { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + Display::fmt(&self.0, f) + } + } + }; +} + +fuel_type_scalar!(Bytes32, Bytes32); +fuel_type_scalar!(Address, Address); +fuel_type_scalar!(BlockId, Bytes32); +fuel_type_scalar!(AssetId, AssetId); +fuel_type_scalar!(BlobId, BlobId); +fuel_type_scalar!(ContractId, ContractId); +fuel_type_scalar!(Salt, Salt); +fuel_type_scalar!(TransactionId, Bytes32); +fuel_type_scalar!(RelayedTransactionId, Bytes32); +fuel_type_scalar!(Signature, Bytes64); +fuel_type_scalar!(Nonce, Nonce); + +macro_rules! number_scalar { + ($i:ident, $t:ty) => { + #[derive(Debug, Clone, derive_more::Into, derive_more::From, PartialOrd, Eq, PartialEq)] + pub struct $i(pub $t); + impl_scalar!($i, schema::$i); + + impl Serialize for $i { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + let s = self.0.to_string(); + serializer.serialize_str(s.as_str()) + } + } + + impl<'de> Deserialize<'de> for $i { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = Deserialize::deserialize(deserializer)?; + Ok(Self(s.parse().map_err(D::Error::custom)?)) + } + } + }; +} + +impl> From> for ConnectionArgs { + fn from(req: PaginationRequest) -> Self { + match req.direction { + PageDirection::Forward => Self { + after: req.cursor.map(Into::into), + before: None, + first: Some(req.results), + last: None, + }, + PageDirection::Backward => Self { + after: None, + before: req.cursor.map(Into::into), + first: None, + last: Some(req.results), + }, + } + } +} + +number_scalar!(U64, u64); +number_scalar!(U32, u32); +number_scalar!(U16, u16); +impl_scalar!(Tai64Timestamp, schema::Tai64Timestamp); +impl_scalar!(HexString, schema::HexString); + +/// Generic graphql pagination query args +#[derive(cynic::QueryVariables, Debug, Default)] +pub struct ConnectionArgs { + /// Skip until cursor (forward pagination) + pub after: Option, + /// Skip until cursor (backward pagination) + pub before: Option, + /// Retrieve the first n items in order (forward pagination) + pub first: Option, + /// Retrieve the last n items in order (backward pagination). + /// Can't be used at the same time as `first`. + pub last: Option, +} + +#[derive(cynic::Enum, Clone, Debug)] +pub enum HeaderVersion { + V1, +} + +#[derive(cynic::Enum, Clone, Copy, Debug)] +pub enum ReceiptType { + Call, + Return, + ReturnData, + Panic, + Revert, + Log, + LogData, + Transfer, + TransferOut, + ScriptResult, + MessageOut, + Mint, + Burn, +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +pub struct Receipt { + pub param1: Option, + pub param2: Option, + pub amount: Option, + pub asset_id: Option, + pub gas: Option, + pub digest: Option, + pub id: Option, + pub is: Option, + pub pc: Option, + pub ptr: Option, + pub ra: Option, + pub rb: Option, + pub rc: Option, + pub rd: Option, + pub reason: Option, + pub receipt_type: ReceiptType, + pub data: Option, + pub to: Option, + pub to_address: Option
, + pub val: Option, + pub len: Option, + pub result: Option, + pub gas_used: Option, + pub sender: Option
, + pub recipient: Option
, + pub nonce: Option, + pub contract_id: Option, + pub sub_id: Option, +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +pub struct Header { + pub height: U32, +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +pub struct SuccessStatus { + pub receipts: Vec, +} + +#[allow(clippy::enum_variant_names)] +#[derive(cynic::InlineFragments, Clone, Debug)] +pub enum TransactionStatus { + SuccessStatus(SuccessStatus), + #[cynic(fallback)] + Unknown, +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +#[cynic(graphql_type = "Transaction")] +pub struct Transaction { + pub id: TransactionId, + pub is_script: bool, + pub input_contracts: Option>, + pub status: Option, +} + +impl Transaction { + pub fn extract_receipts(&self) -> Option> { + if let TransactionStatus::SuccessStatus(status) = self.status.clone()? { + let receipts = status + .receipts + .into_iter() + .filter_map(|receipt| generate_receipt(receipt).ok()) + .collect::>(); + return Some(receipts); + } + None + } + + pub fn is_valid(&self) -> bool { + self.status + .clone() + .is_some_and(|status| matches!(status, TransactionStatus::SuccessStatus(_))) + && self.is_script + && self.input_contracts.is_some() + } +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +#[cynic(graphql_type = "Block")] +pub struct Block { + pub id: BlockId, + pub header: Header, + pub transactions: Vec, +} + +#[derive(cynic::QueryFragment, Debug, Clone)] +#[cynic(graphql_type = "Query", variables = "ConnectionArgs")] +pub struct BlocksQuery { + #[arguments(after: $after, before: $before, first: $first, last: $last)] + pub blocks: BlockConnection, +} + +#[derive(cynic::QueryFragment, Clone, Debug)] +pub struct BlockConnection { + pub nodes: Vec, +} diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs index 4afbb2700c..d5d3b54020 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs @@ -1,18 +1,21 @@ -use crate::{ - contracts::interchain_gas_paymaster::{ - GasPaymentEvent, InterchainGasPaymaster as InterchainGasPaymasterContract, - }, - conversions::*, - ConnectionConf, FuelIndexer, FuelProvider, -}; +use std::ops::RangeInclusive; + use async_trait::async_trait; use fuels::{accounts::wallet::WalletUnlocked, types::bech32::Bech32ContractId}; + use hyperlane_core::{ ChainResult, ContractLocator, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneProvider, Indexed, Indexer, InterchainGasPaymaster, InterchainGasPayment, LogMeta, SequenceAwareIndexer, H256, }; -use std::ops::RangeInclusive; + +use crate::{ + contracts::interchain_gas_paymaster::{ + GasPaymentEvent, InterchainGasPaymaster as InterchainGasPaymasterContract, + }, + conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, +}; /// A reference to an IGP contract on some Fuel chain #[derive(Debug)] @@ -78,7 +81,6 @@ impl FuelInterchainGasPaymasterIndexer { wallet: WalletUnlocked, ) -> ChainResult { let indexer = FuelIndexer::new(conf, locator, wallet).await; - Ok(Self { indexer }) } } @@ -100,7 +102,7 @@ impl Indexer for FuelInterchainGasPaymasterIndexer { #[async_trait] impl SequenceAwareIndexer for FuelInterchainGasPaymasterIndexer { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { - // TODO: implement when fuel scraper support is implemented + // No sequence for gas payments let tip = self.get_finalized_block_number().await?; Ok((None, tip)) } diff --git a/rust/main/chains/hyperlane-fuel/src/lib.rs b/rust/main/chains/hyperlane-fuel/src/lib.rs index 40acc665a1..8caf971a5e 100644 --- a/rust/main/chains/hyperlane-fuel/src/lib.rs +++ b/rust/main/chains/hyperlane-fuel/src/lib.rs @@ -12,7 +12,6 @@ mod aggregation_ism; mod contracts; mod conversions; mod indexer; -mod indexer_events; mod interchain_gas; mod interchain_security_module; mod mailbox; diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index ebf1ca3915..de903840c3 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -1,8 +1,8 @@ -use crate::{ - contracts::mailbox::{DispatchEvent, Mailbox as FuelMailboxContract}, - conversions::*, - ConnectionConf, FuelIndexer, FuelProvider, +use std::{ + fmt::{Debug, Formatter}, + ops::RangeInclusive, }; + use async_trait::async_trait; use fuels::{ prelude::{Bech32ContractId, WalletUnlocked}, @@ -10,18 +10,20 @@ use fuels::{ tx::{Receipt, ScriptExecutionResult}, types::{transaction::TxPolicies, transaction_builders::VariableOutputPolicy, Bytes}, }; +use tracing::{instrument, warn}; + use hyperlane_core::{ - utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, HyperlaneAbi, + utils::bytes_to_hex, ChainCommunicationError, ChainResult, ContractLocator, Delivery, HyperlaneChain, HyperlaneContract, HyperlaneDomain, HyperlaneMessage, HyperlaneProvider, Indexed, Indexer, LogMeta, Mailbox, RawHyperlaneMessage, ReorgPeriod, SequenceAwareIndexer, TxCostEstimate, TxOutcome, H256, H512, U256, }; -use std::{ - collections::HashMap, - fmt::{Debug, Formatter}, - ops::RangeInclusive, + +use crate::{ + contracts::mailbox::{DispatchEvent, Mailbox as FuelMailboxContract, ProcessIdEvent}, + conversions::*, + ConnectionConf, FuelIndexer, FuelProvider, }; -use tracing::{instrument, warn}; const GAS_ESTIMATE_MULTIPLIER: f64 = 1.3; /// A reference to a Mailbox contract on some Fuel chain @@ -232,17 +234,17 @@ impl Mailbox for FuelMailbox { } // ---------------------------------------------------------- -// ---------------------- Indexer --------------------------- +// ------------------ Dispatch Indexer ---------------------- // ---------------------------------------------------------- -/// Struct that retrieves event data for a Fuel Mailbox contract +/// Struct that retrieves Dispatch events from a Fuel Mailbox contract #[derive(Debug)] -pub struct FuelMailboxIndexer { +pub struct FuelDispatchIndexer { indexer: FuelIndexer, contract: FuelMailboxContract, } -impl FuelMailboxIndexer { +impl FuelDispatchIndexer { /// Create a new FuelMailboxIndexer pub async fn new( conf: &ConnectionConf, @@ -260,7 +262,7 @@ impl FuelMailboxIndexer { } #[async_trait] -impl Indexer for FuelMailboxIndexer { +impl Indexer for FuelDispatchIndexer { async fn fetch_logs_in_range( &self, range: RangeInclusive, @@ -274,31 +276,7 @@ impl Indexer for FuelMailboxIndexer { } #[async_trait] -impl Indexer for FuelMailboxIndexer { - async fn fetch_logs_in_range( - &self, - _range: RangeInclusive, - ) -> ChainResult, LogMeta)>> { - todo!() // Needed for scraper - } - - async fn get_finalized_block_number(&self) -> ChainResult { - self.indexer.provider().get_finalized_block_number().await - } -} - -#[async_trait] -impl SequenceAwareIndexer for FuelMailboxIndexer { - async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { - let tip = Indexer::::get_finalized_block_number(&self).await?; - - // No sequence for message deliveries. - Ok((None, tip)) - } -} - -#[async_trait] -impl SequenceAwareIndexer for FuelMailboxIndexer { +impl SequenceAwareIndexer for FuelDispatchIndexer { async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { let tip = Indexer::::get_finalized_block_number(&self).await?; @@ -313,14 +291,47 @@ impl SequenceAwareIndexer for FuelMailboxIndexer { } } -#[allow(dead_code)] -struct FuelMailboxAbi; +// ---------------------------------------------------------- +// ------------------ Delivery Indexer ---------------------- +// ---------------------------------------------------------- + +/// Struct that retrieves ProcessId events from a Fuel Mailbox contract +#[derive(Debug)] +pub struct FuelDeliveryIndexer { + indexer: FuelIndexer, +} + +impl FuelDeliveryIndexer { + /// Create a new FuelMailboxIndexer + pub async fn new( + conf: &ConnectionConf, + locator: ContractLocator<'_>, + wallet: WalletUnlocked, + ) -> ChainResult { + let indexer = FuelIndexer::new(conf, locator, wallet).await; + Ok(Self { indexer }) + } +} + +#[async_trait] +impl Indexer for FuelDeliveryIndexer { + async fn fetch_logs_in_range( + &self, + range: RangeInclusive, + ) -> ChainResult, LogMeta)>> { + self.indexer.index_logs_in_range(range).await + } -impl HyperlaneAbi for FuelMailboxAbi { - const SELECTOR_SIZE_BYTES: usize = 8; + async fn get_finalized_block_number(&self) -> ChainResult { + self.indexer.provider().get_finalized_block_number().await + } +} - fn fn_map() -> HashMap, &'static str> { - // Can't support this without Fuels exporting it in the generated code - todo!() +#[async_trait] +impl SequenceAwareIndexer for FuelDeliveryIndexer { + async fn latest_sequence_count_and_tip(&self) -> ChainResult<(Option, u32)> { + let tip = Indexer::::get_finalized_block_number(&self).await?; + // No sequence for message deliveries. + Ok((None, tip)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index 5a3cb7ee3f..421b716ba8 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -1,14 +1,15 @@ -use crate::{make_client, make_provider, ConnectionConf}; +use crate::{make_client, make_provider, prelude::FuelIntoH256, ConnectionConf}; + use async_trait::async_trait; use fuels::{ client::FuelClient, prelude::Provider, - tx::Receipt, - types::{transaction::TransactionType, tx_status::TxStatus, Address, BlockHeight, ContractId}, + types::{Address, BlockHeight, ContractId}, }; use hyperlane_core::{ h512_to_bytes, BlockInfo, ChainCommunicationError, ChainInfo, ChainResult, HyperlaneChain, - HyperlaneDomain, HyperlaneProvider, HyperlaneProviderError, TxnInfo, H256, H512, U256, + HyperlaneDomain, HyperlaneProvider, HyperlaneProviderError, TxnInfo, TxnReceiptInfo, H256, + H512, U256, }; /// A wrapper around a fuel provider to get generic blockchain information. @@ -54,34 +55,6 @@ impl FuelProvider { .await .map_err(ChainCommunicationError::from_other) } - - /// Extract transaction data from receipts - fn extract_transaction_data(receipts: Vec) -> (H256, Option, u64) { - let valid_receipt = receipts - .into_iter() - .find(|receipt| matches!(receipt, Receipt::MessageOut { .. })); - - match valid_receipt { - Some(Receipt::MessageOut { - sender, - recipient, - nonce, - .. - }) => { - let mut arr = [0u8; 8]; - let nonce_bytes = <[u8; 32]>::from(nonce); - arr.copy_from_slice(&nonce_bytes[0..8]); - let parsed_nonce = u64::from_be_bytes(arr); - - ( - <[u8; 32]>::from(sender).into(), - Some(<[u8; 32]>::from(recipient).into()), - parsed_nonce, - ) - } - _ => (H256::zero(), None, 0), - } - } } impl HyperlaneChain for FuelProvider { @@ -106,7 +79,7 @@ impl HyperlaneProvider for FuelProvider { let block_info = match block_res { Some(block) => BlockInfo { - hash: H256::from_slice(block.id.as_slice()), + hash: block.id.into_h256(), timestamp: block.header.time.map_or(0, |t| t.timestamp() as u64), number: block.header.height.into(), }, @@ -123,54 +96,75 @@ impl HyperlaneProvider for FuelProvider { Ok(block_info) } - /// Used by scraper + /// Get a transaction by its hash async fn get_txn_by_hash(&self, hash: &H512) -> ChainResult { let hash_parsed = H256::from_slice(&h512_to_bytes(hash)); - let transaction_res = self + let transaction = self .provider .get_transaction_by_id(&hash_parsed.0.into()) .await - .map_err(|_| HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))?; - - match transaction_res { - Some(transaction) => { - let block_number = transaction.block_height.unwrap(); - - let gas_price = self - .provider - .estimate_gas_price(block_number.into()) - .await - .map_or(0, |estimate| estimate.gas_price); - - let gas_limit = match transaction.transaction { - TransactionType::Script(tx) => tx.gas_limit(), - _ => 0, - }; - - let (sender, recipient, nonce) = match transaction.status { - TxStatus::Success { receipts } => Self::extract_transaction_data(receipts), - _ => (H256::zero(), None, 0), - }; - - Ok(TxnInfo { - hash: *hash, - gas_limit: gas_limit.into(), - max_priority_fee_per_gas: None, - max_fee_per_gas: None, - nonce, - sender, - gas_price: Some(gas_price.into()), - recipient, - receipt: None, - raw_input_data: None, - }) - } - None => Err(ChainCommunicationError::CustomError(format!( - "Transaction not found: {}", - hash - ))), - } + .map_err(|_| HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))? + .ok_or_else(|| HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))?; + + let block_number = transaction.block_height.ok_or_else(|| { + ChainCommunicationError::from_other_str( + "Could not get block number from transaction data", + ) + })?; + + let gas_price = self + .provider + .estimate_gas_price(block_number.into()) + .await + .map_or(0, |estimate| estimate.gas_price); + + let receipts = transaction.status.take_receipts(); + + let gas_used = receipts + .iter() + .filter_map(|receipt| receipt.gas_used()) + .next() + .unwrap_or(0); + let sender = receipts + .iter() + .filter_map(|receipt| receipt.sender()) + .next() + .map(|sender| H256::from_slice(&sender.as_slice())) + .unwrap_or(H256::zero()); + let recipient = receipts + .iter() + .filter_map(|receipt| receipt.recipient()) + .next() + .map(|recipient| H256::from_slice(&recipient.as_slice())); + let nonce = receipts + .iter() + .filter_map(|receipt| receipt.nonce()) + .next() + .map(|nonce| { + let mut arr = [0u8; 8]; + let nonce_bytes = <[u8; 32]>::from(*nonce); + arr.copy_from_slice(&nonce_bytes[0..8]); + u64::from_be_bytes(arr) + }) + .unwrap_or(0); + + Ok(TxnInfo { + hash: *hash, + gas_limit: gas_used.into(), + max_priority_fee_per_gas: None, + max_fee_per_gas: None, + nonce, + sender, + gas_price: Some(gas_price.into()), + recipient, + receipt: Some(TxnReceiptInfo { + gas_used: gas_used.into(), + cumulative_gas_used: gas_used.into(), + effective_gas_price: Some(gas_price.into()), + }), + raw_input_data: None, + }) } async fn is_contract(&self, address: &H256) -> ChainResult { @@ -185,6 +179,7 @@ impl HyperlaneProvider for FuelProvider { } } + /// Get the base asset balance of an address async fn get_balance(&self, address: String) -> ChainResult { let base = self.provider.base_asset_id(); let address_bytes = hex::decode(&address)?; @@ -201,8 +196,31 @@ impl HyperlaneProvider for FuelProvider { })? } - /// Used by hyperlane base metrics (scraper) + /// Get the chain metrics for the latest block async fn get_chain_metrics(&self) -> ChainResult> { - Ok(None) + let metrics = self + .provider + .latest_gas_price() + .await + .map_err(|_| ChainCommunicationError::from_other_str("Failed to get gas price"))?; + let block_info = self + .provider + .block_by_height(metrics.block_height) + .await + .map_err(|_| { + HyperlaneProviderError::CouldNotFindBlockByHeight(*metrics.block_height as u64) + })? + .ok_or_else(|| { + HyperlaneProviderError::CouldNotFindBlockByHeight(*metrics.block_height as u64) + })?; + + Ok(Some(ChainInfo { + latest_block: BlockInfo { + hash: block_info.id.into_h256(), + timestamp: block_info.header.time.map_or(0, |t| t.timestamp() as u64), + number: block_info.header.height.into(), + }, + min_gas_price: Some(U256::from(metrics.gas_price)), + })) } } diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index d4d7b10492..92ae02381b 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -292,7 +292,7 @@ impl ChainConf { ChainConnectionConf::Fuel(conf) => { let wallet = self.fuel_signer().await.context(ctx)?; let indexer = - Box::new(h_fuel::FuelMailboxIndexer::new(conf, locator, wallet).await?); + Box::new(h_fuel::FuelDispatchIndexer::new(conf, locator, wallet).await?); Ok(indexer as Box>) } ChainConnectionConf::Sealevel(conf) => { @@ -334,7 +334,12 @@ impl ChainConf { ) .await } - ChainConnectionConf::Fuel(_) => todo!("Fuel does not have scraper support yet"), + ChainConnectionConf::Fuel(conf) => { + let wallet = self.fuel_signer().await.context(ctx)?; + let indexer = + Box::new(h_fuel::FuelDeliveryIndexer::new(conf, locator, wallet).await?); + Ok(indexer as Box>) + } ChainConnectionConf::Sealevel(conf) => { let indexer = Box::new(h_sealevel::SealevelMailboxIndexer::new(conf, locator)?); Ok(indexer as Box>) From 68562f1a0257acc88b5a623548227a3844d1904d Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Thu, 30 Jan 2025 10:01:55 +0100 Subject: [PATCH 21/31] feat(fuel-integration): fuel contract abi updates --- .../abis/AggregationISM.abi.json | 1238 +++++++++------- .../abis/InterchainGasPaymaster.abi.json | 1282 +++++++++++------ .../abis/InterchainSecurityModule.abi.json | 963 ++++++++----- .../hyperlane-fuel/abis/Mailbox.abi.json | 601 ++------ .../abis/MerkleTreeHook.abi.json | 323 ++--- .../hyperlane-fuel/abis/MultisigISM.abi.json | 308 ++-- .../hyperlane-fuel/abis/RoutingISM.abi.json | 526 +++++-- .../abis/ValidatorAnnounce.abi.json | 208 +-- 8 files changed, 2964 insertions(+), 2485 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json index c0c2c90bd6..29ea15103a 100644 --- a/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/AggregationISM.abi.json @@ -1,559 +1,681 @@ { - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "(struct std::vec::Vec, u8)", - "concreteTypeId": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", - "metadataTypeId": 0 - }, - { - "type": "b256", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - }, - { - "type": "bool", - "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" - }, - { - "type": "enum AggregationIsmError", - "concreteTypeId": "0ea8621ef67fa15d0d7ae795a3f434f12a683909e6c2096ed7ba493fa6dba43a", - "metadataTypeId": 1 - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "metadataTypeId": 2 - }, - { - "type": "enum standards::src5::AccessError", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", - "metadataTypeId": 3 - }, - { - "type": "enum standards::src5::State", - "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "metadataTypeId": 4 - }, - { - "type": "enum std::identity::Identity", - "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", - "metadataTypeId": 5 - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", - "metadataTypeId": 6 - }, - { - "type": "struct std::bytes::Bytes", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 10 - }, - { - "type": "struct std::contract_id::ContractId", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 12 - }, - { - "type": "struct sway_libs::ownership::events::OwnershipRenounced", - "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", - "metadataTypeId": 15 - }, - { - "type": "struct sway_libs::ownership::events::OwnershipSet", - "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", - "metadataTypeId": 16 - }, - { - "type": "struct sway_libs::ownership::events::OwnershipTransferred", - "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", - "metadataTypeId": 17 - }, - { - "type": "u8", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "metadataTypes": [ - { - "type": "(_, _)", - "metadataTypeId": 0, - "components": [ - { - "name": "__tuple_element", - "typeId": 14, - "typeArguments": [ - { - "name": "", - "typeId": 12 - } - ] - }, - { - "name": "__tuple_element", - "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ] - }, - { - "type": "enum AggregationIsmError", - "metadataTypeId": 1, - "components": [ - { - "name": "DidNotMeetThreshold", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "AlreadyInitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NotInitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "metadataTypeId": 2, - "components": [ - { - "name": "UNUSED", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "ROUTING", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "AGGREGATION", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "LEGACY_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MERKLE_ROOT_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MESSAGE_ID_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NULL", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "CCIP_READ", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "ARB_L2_TO_L1", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum standards::src5::AccessError", - "metadataTypeId": 3, - "components": [ - { - "name": "NotOwner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum standards::src5::State", - "metadataTypeId": 4, - "components": [ - { - "name": "Uninitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "Initialized", - "typeId": 5 - }, - { - "name": "Revoked", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "enum std::identity::Identity", - "metadataTypeId": 5, - "components": [ - { - "name": "Address", - "typeId": 9 - }, - { - "name": "ContractId", - "typeId": 12 - } - ] - }, - { - "type": "enum sway_libs::ownership::errors::InitializationError", - "metadataTypeId": 6, - "components": [ - { - "name": "CannotReinitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 7 - }, - { - "type": "raw untyped ptr", - "metadataTypeId": 8 - }, - { - "type": "struct std::address::Address", - "metadataTypeId": 9, - "components": [ - { - "name": "bits", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - } - ] - }, - { - "type": "struct std::bytes::Bytes", - "metadataTypeId": 10, - "components": [ - { - "name": "buf", - "typeId": 11 - }, - { - "name": "len", - "typeId": 18 - } - ] - }, - { - "type": "struct std::bytes::RawBytes", - "metadataTypeId": 11, - "components": [ - { - "name": "ptr", - "typeId": 8 - }, - { - "name": "cap", - "typeId": 18 - } - ] - }, - { - "type": "struct std::contract_id::ContractId", - "metadataTypeId": 12, - "components": [ - { - "name": "bits", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - } - ] - }, - { - "type": "struct std::vec::RawVec", - "metadataTypeId": 13, - "components": [ - { - "name": "ptr", - "typeId": 8 - }, - { - "name": "cap", - "typeId": 18 - } - ], - "typeParameters": [ - 7 - ] - }, - { - "type": "struct std::vec::Vec", - "metadataTypeId": 14, - "components": [ - { - "name": "buf", - "typeId": 13, - "typeArguments": [ - { - "name": "", - "typeId": 7 - } - ] - }, - { - "name": "len", - "typeId": 18 - } - ], - "typeParameters": [ - 7 - ] - }, - { - "type": "struct sway_libs::ownership::events::OwnershipRenounced", - "metadataTypeId": 15, - "components": [ - { - "name": "previous_owner", - "typeId": 5 - } - ] - }, - { - "type": "struct sway_libs::ownership::events::OwnershipSet", - "metadataTypeId": 16, - "components": [ - { - "name": "new_owner", - "typeId": 5 - } - ] - }, - { - "type": "struct sway_libs::ownership::events::OwnershipTransferred", - "metadataTypeId": 17, - "components": [ - { - "name": "new_owner", - "typeId": 5 - }, - { - "name": "previous_owner", - "typeId": 5 - } - ] - }, - { - "type": "u64", - "metadataTypeId": 18 - } - ], - "functions": [ - { - "inputs": [], - "name": "module_type", - "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "attributes": null - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "verify", - "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "modules_and_threshold", - "output": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "module", - "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" - } - ], - "name": "enroll_module", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "owner", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" - } - ], - "name": "initialize", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "threshold", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "name": "set_threshold", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_owner", - "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" - } - ], - "name": "initialize_ownership", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [], - "name": "only_owner", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "owner", - "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "renounce_ownership", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read", - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "new_owner", - "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" - } - ], - "name": "transfer_ownership", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "1056201997742481757", - "concreteTypeId": "0ea8621ef67fa15d0d7ae795a3f434f12a683909e6c2096ed7ba493fa6dba43a" - }, - { - "logId": "4571204900286667806", - "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" - }, - { - "logId": "2161305517876418151", - "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" - }, - { - "logId": "16280289466020123285", - "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" - }, - { - "logId": "4883303303013154842", - "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" - }, - { - "logId": "12970362301975156672", - "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" - } - ], - "messagesTypes": [], - "configurables": [] - } \ No newline at end of file + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::isms::aggregation_ism::AggregationIsmError", + "concreteTypeId": "d132a0a455da99b27af77b6df0f334147b4f0872c3f22da9d452ab0baba6e461", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 3 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 4 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 5 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 6 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 7 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 11 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 13 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "b8ca7626a08e8fb93379b5d9d58d8a12eede8de9f087bfa21feccca44f92e211", + "metadataTypeId": 15, + "typeArguments": [ + "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 17 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 18 + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 15, + "typeArguments": [ + { + "name": "", + "typeId": 13 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::aggregation_ism::AggregationIsmError", + "metadataTypeId": 2, + "components": [ + { + "name": "DidNotMeetThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 3, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 4, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 5, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 6 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 6, + "components": [ + { + "name": "Address", + "typeId": 10 + }, + { + "name": "ContractId", + "typeId": 13 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 7, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 8 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 9 + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 11, + "components": [ + { + "name": "buf", + "typeId": 12 + }, + { + "name": "len", + "typeId": 19 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 12, + "components": [ + { + "name": "ptr", + "typeId": 9 + }, + { + "name": "cap", + "typeId": 19 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 13, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 14, + "components": [ + { + "name": "ptr", + "typeId": 9 + }, + { + "name": "cap", + "typeId": 19 + } + ], + "typeParameters": [8] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 15, + "components": [ + { + "name": "buf", + "typeId": 14, + "typeArguments": [ + { + "name": "", + "typeId": 8 + } + ] + }, + { + "name": "len", + "typeId": 19 + } + ], + "typeParameters": [8] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 16, + "components": [ + { + "name": "previous_owner", + "typeId": 6 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 6 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 18, + "components": [ + { + "name": "new_owner", + "typeId": 6 + }, + { + "name": "previous_owner", + "typeId": 6 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 19 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [ModuleType] - The type of security model."] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Verifies the message using the metadata."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message to be verified."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If any external call fails."] + }, + { + "name": "doc-comment", + "arguments": [" * If the verifications do not meet the threshold."] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "modules_and_threshold", + "output": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the modules and threshold for the Aggregation ISM for the given message." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message to be processed."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of modules to be used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u8] - The threshold of approval for the Aggregation ISM." + ] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "modules", + "concreteTypeId": "b8ca7626a08e8fb93379b5d9d58d8a12eede8de9f087bfa21feccca44f92e211" + }, + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Initializes the contract."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * `owner`: [Identity] - The address to be set as the owner of the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the contract is already initialized."] + }, + { + "name": "storage", + "arguments": ["read", "write"] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": ["read", "write"] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": ["read", "write"] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": ["write"] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "15074287530437941682", + "concreteTypeId": "d132a0a455da99b27af77b6df0f334147b4f0872c3f22da9d452ab0baba6e461" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} diff --git a/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json b/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json index 877ba212b1..3e47301fa9 100644 --- a/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/InterchainGasPaymaster.abi.json @@ -12,37 +12,54 @@ "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { - "type": "enum IgpError", - "concreteTypeId": "5e9b943fe66bb2f9186016140592021f71cf98395bd3c80eef479a17a9b39e2b", + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::hooks::igp::IgpError", + "concreteTypeId": "e8ec08fc35b6312eaeca1be8ba0645b2eb1bf5656f53fed618eda7c184a7c6bc", "metadataTypeId": 0 }, + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "concreteTypeId": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "metadataTypeId": 1 + }, { "type": "enum standards::src5::AccessError", "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", - "metadataTypeId": 1 + "metadataTypeId": 2 }, { "type": "enum standards::src5::State", "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", - "metadataTypeId": 2 + "metadataTypeId": 3 }, { "type": "enum std::identity::Identity", "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", - "metadataTypeId": 3 + "metadataTypeId": 4 }, { "type": "enum std::option::Option", "concreteTypeId": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", - "metadataTypeId": 4, + "metadataTypeId": 5, "typeArguments": [ "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" ] }, + { + "type": "enum std::option::Option", + "concreteTypeId": "191bf2140761b3c5ab6c43992d162bb3dc9d7f2272b2ee5f5eeea411ddedcd32", + "metadataTypeId": 5, + "typeArguments": [ + "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974" + ] + }, { "type": "enum std::option::Option", "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", - "metadataTypeId": 4, + "metadataTypeId": 5, "typeArguments": [ "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" ] @@ -50,46 +67,87 @@ { "type": "enum sway_libs::ownership::errors::InitializationError", "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", - "metadataTypeId": 5 + "metadataTypeId": 6 }, { "type": "str", "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" }, { - "type": "struct interfaces::claimable::BeneficiarySetEvent", - "concreteTypeId": "28da8704d9711bb3e5ae8de91a1339201b6e3a044065e47395c1f4064d8e07d8", - "metadataTypeId": 7 + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "concreteTypeId": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "metadataTypeId": 9 }, { - "type": "struct interfaces::claimable::ClaimEvent", - "concreteTypeId": "6bcec70a463a07509f86d07955802bee953038650739d9b15f8ba95a0e2052aa", - "metadataTypeId": 8 + "type": "struct interfaces::hooks::igp::BeneficiarySetEvent", + "concreteTypeId": "229f9e763c8424886a0b828eb92ecd7ee7ee60fb9b34ec5595a43cc02b21a6e7", + "metadataTypeId": 10 }, { - "type": "struct interfaces::igp::GasOracleSetEvent", - "concreteTypeId": "e2a62dd30c887a49893c650f8f85200415866051cadc94f195537b3798498065", - "metadataTypeId": 9 + "type": "struct interfaces::hooks::igp::ClaimEvent", + "concreteTypeId": "f6197f499ee863b7f79af9d4149ec4c76ac1f12af5d55ac5a3e9aa2adf195bc9", + "metadataTypeId": 11 }, { - "type": "struct interfaces::igp::GasPaymentEvent", - "concreteTypeId": "57f16a22cb9e861b379fae117dc32f53512234a762ed50564496dff7600646b9", - "metadataTypeId": 10 + "type": "struct interfaces::hooks::igp::DestinationGasConfigSetEvent", + "concreteTypeId": "b8b47e85d8cb1e8bd7a47922d6ac2c9aef8c272feb8d5a404e972bb189aeedb3", + "metadataTypeId": 12 + }, + { + "type": "struct interfaces::hooks::igp::DomainGasConfig", + "concreteTypeId": "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b", + "metadataTypeId": 13 + }, + { + "type": "struct interfaces::hooks::igp::GasOracleSetEvent", + "concreteTypeId": "9a9d03fe63ecba2bda69c30f8c743b0d5719d4dc01ad2cbbedce34332ae57970", + "metadataTypeId": 14 + }, + { + "type": "struct interfaces::hooks::igp::GasPaymentEvent", + "concreteTypeId": "8dfafd11d278da7cc3347b4432a7bd4dbb4dbc21d2475f98b8ae17b0a1a5c122", + "metadataTypeId": 15 + }, + { + "type": "struct std::asset_id::AssetId", + "concreteTypeId": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974", + "metadataTypeId": 17 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 18 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "72e5e46f1e7d3f8964a9236d110d456cb86fea809e436c91f60e6503b65f9f1d", + "metadataTypeId": 23, + "typeArguments": [ + "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "metadataTypeId": 23, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] }, { "type": "struct sway_libs::ownership::events::OwnershipRenounced", "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", - "metadataTypeId": 13 + "metadataTypeId": 24 }, { "type": "struct sway_libs::ownership::events::OwnershipSet", "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", - "metadataTypeId": 14 + "metadataTypeId": 25 }, { "type": "struct sway_libs::ownership::events::OwnershipTransferred", "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", - "metadataTypeId": 15 + "metadataTypeId": 26 }, { "type": "u32", @@ -106,7 +164,7 @@ ], "metadataTypes": [ { - "type": "enum IgpError", + "type": "enum interfaces::hooks::igp::IgpError", "metadataTypeId": 0, "components": [ { @@ -114,26 +172,72 @@ "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "InvalidGasOracle", + "name": "InterchainGasPaymentInBaseAsset", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "QuoteGasPaymentOverflow", + "name": "UnsupportedMetadataFormat", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "InterchainGasPaymentInBaseAsset", + "name": "InvalidDomainConfigLength", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "metadataTypeId": 1, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_TREE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "INTERCHAIN_GAS_PAYMASTER", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FALLBACK_ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ID_AUTH_ISM", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PAUSABLE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PROTOCOL_FEE", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "ContractAlreadyInitialized", + "name": "LAYER_ZERO_V1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "RATE_LIMITED_HOOK", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" } ] }, { "type": "enum standards::src5::AccessError", - "metadataTypeId": 1, + "metadataTypeId": 2, "components": [ { "name": "NotOwner", @@ -143,7 +247,7 @@ }, { "type": "enum standards::src5::State", - "metadataTypeId": 2, + "metadataTypeId": 3, "components": [ { "name": "Uninitialized", @@ -151,7 +255,7 @@ }, { "name": "Initialized", - "typeId": 3 + "typeId": 4 }, { "name": "Revoked", @@ -161,21 +265,21 @@ }, { "type": "enum std::identity::Identity", - "metadataTypeId": 3, + "metadataTypeId": 4, "components": [ { "name": "Address", - "typeId": 11 + "typeId": 16 }, { "name": "ContractId", - "typeId": 12 + "typeId": 20 } ] }, { "type": "enum std::option::Option", - "metadataTypeId": 4, + "metadataTypeId": 5, "components": [ { "name": "None", @@ -183,16 +287,14 @@ }, { "name": "Some", - "typeId": 6 + "typeId": 7 } ], - "typeParameters": [ - 6 - ] + "typeParameters": [7] }, { "type": "enum sway_libs::ownership::errors::InitializationError", - "metadataTypeId": 5, + "metadataTypeId": 6, "components": [ { "name": "CannotReinitialized", @@ -202,25 +304,51 @@ }, { "type": "generic T", - "metadataTypeId": 6 + "metadataTypeId": 7 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 8 + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "metadataTypeId": 9, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "token_exchange_rate", + "typeId": 21 + }, + { + "name": "gas_price", + "typeId": 21 + }, + { + "name": "token_decimals", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] }, { - "type": "struct interfaces::claimable::BeneficiarySetEvent", - "metadataTypeId": 7, + "type": "struct interfaces::hooks::igp::BeneficiarySetEvent", + "metadataTypeId": 10, "components": [ { "name": "beneficiary", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "typeId": 4 } ] }, { - "type": "struct interfaces::claimable::ClaimEvent", - "metadataTypeId": 8, + "type": "struct interfaces::hooks::igp::ClaimEvent", + "metadataTypeId": 11, "components": [ { "name": "beneficiary", - "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "typeId": 4 }, { "name": "amount", @@ -229,8 +357,40 @@ ] }, { - "type": "struct interfaces::igp::GasOracleSetEvent", - "metadataTypeId": 9, + "type": "struct interfaces::hooks::igp::DestinationGasConfigSetEvent", + "metadataTypeId": 12, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "overhead", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::DomainGasConfig", + "metadataTypeId": 13, + "components": [ + { + "name": "gas_oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "gas_overhead", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::GasOracleSetEvent", + "metadataTypeId": 14, "components": [ { "name": "domain", @@ -243,8 +403,8 @@ ] }, { - "type": "struct interfaces::igp::GasPaymentEvent", - "metadataTypeId": 10, + "type": "struct interfaces::hooks::igp::GasPaymentEvent", + "metadataTypeId": 15, "components": [ { "name": "message_id", @@ -266,7 +426,17 @@ }, { "type": "struct std::address::Address", - "metadataTypeId": 11, + "metadataTypeId": 16, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::asset_id::AssetId", + "metadataTypeId": 17, "components": [ { "name": "bits", @@ -274,9 +444,37 @@ } ] }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 18, + "components": [ + { + "name": "buf", + "typeId": 19 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 19, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, { "type": "struct std::contract_id::ContractId", - "metadataTypeId": 12, + "metadataTypeId": 20, "components": [ { "name": "bits", @@ -284,42 +482,145 @@ } ] }, + { + "type": "struct std::u128::U128", + "metadataTypeId": 21, + "components": [ + { + "name": "upper", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "lower", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 22, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [7] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 23, + "components": [ + { + "name": "buf", + "typeId": 22, + "typeArguments": [ + { + "name": "", + "typeId": 7 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [7] + }, { "type": "struct sway_libs::ownership::events::OwnershipRenounced", - "metadataTypeId": 13, + "metadataTypeId": 24, "components": [ { "name": "previous_owner", - "typeId": 3 + "typeId": 4 } ] }, { "type": "struct sway_libs::ownership::events::OwnershipSet", - "metadataTypeId": 14, + "metadataTypeId": 25, "components": [ { "name": "new_owner", - "typeId": 3 + "typeId": 4 } ] }, { "type": "struct sway_libs::ownership::events::OwnershipTransferred", - "metadataTypeId": 15, + "metadataTypeId": 26, "components": [ { "name": "new_owner", - "typeId": 3 + "typeId": 4 }, { "name": "previous_owner", - "typeId": 3 + "typeId": 4 } ] } ], "functions": [ + { + "inputs": [], + "name": "beneficiary", + "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Gets the current beneficiary."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [Identity] - The beneficiary."] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "asset", + "concreteTypeId": "191bf2140761b3c5ab6c43992d162bb3dc9d7f2272b2ee5f5eeea411ddedcd32" + } + ], + "name": "claim", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sends all base asset funds to the beneficiary. Callable by anyone." + ] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, { "inputs": [ { @@ -332,27 +633,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the gas oracle for a domain." - ] + "arguments": [" Returns the gas oracle for a domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -362,9 +655,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -375,145 +666,219 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Gets the gas amount for the current domain." - ] + "arguments": [" Gets the gas amount for the current domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [u64] - The gas amount for the current domain."] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_domain_gas_config", + "output": "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Gets the gas config for a domain."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - "" + " * `domain`: [u32] - The domain to get the gas config for." ] }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, { "name": "doc-comment", "arguments": [ - " * [u64] - The gas amount for the current domain." + " * [DomainGasConfig] - The gas config for the domain (gas overhead and oracle address)." ] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, { "inputs": [ { - "name": "owner", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_remote_gas_data", + "output": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the exchange rate and gas price for a given domain using the" + ] }, { - "name": "beneficiary", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "name": "doc-comment", + "arguments": [" configured gas oracle."] }, { - "name": "token_exchange_rate", - "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + "name": "doc-comment", + "arguments": [""] }, { - "name": "base_asset_decimal", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + "name": "doc-comment", + "arguments": [" ### Arguments"] }, { - "name": "default_gas_amount", - "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" - } - ], - "name": "initialize", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ + "name": "doc-comment", + "arguments": [""] + }, { "name": "doc-comment", "arguments": [ - " Initializes the contract." + " * `domain`: [u32] - The domain to get the gas data for." ] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * `owner`: [b256] - The owner of the contract." + " * [RemoteGasData] - Remote gas data for the domain from the oracle." ] }, { "name": "doc-comment", - "arguments": [ - " * `default_ism`: [b256] - The default ISM contract Id." - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `default_hook`: [b256] - The default hook contract Id." - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - " * `required_hook`: [b256] - The required hook contract Id." - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" * If no gas oracle is set."] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "beneficiary", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Initializes the contract."] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `owner`: [Identity] - The owner of the contract."] }, { "name": "doc-comment", "arguments": [ - " * If the contract is already initialized." + " * `beneficiary`: [Identity] - The beneficiary of the contract." ] }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the contract is already initialized."] + }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -541,33 +906,23 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Allows the caller to pay for gas." - ] + "arguments": [" Allows the caller to pay for gas."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `message_id`: [b256] - The message ID." - ] + "arguments": [" * `message_id`: [b256] - The message ID."] }, { "name": "doc-comment", @@ -577,9 +932,7 @@ }, { "name": "doc-comment", - "arguments": [ - " * `gas_amount`: [u64] - The amount of gas." - ] + "arguments": [" * `gas_amount`: [u64] - The amount of gas."] }, { "name": "doc-comment", @@ -589,33 +942,27 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If asset sent is not the base asset." - ] + "arguments": [" * If asset sent is not the base asset."] }, { "name": "doc-comment", - "arguments": [ - " * If the payment is less than the required amount." - ] + "arguments": [" * If the payment is less than the required amount."] + }, + { + "name": "doc-comment", + "arguments": [" * If the metadata is invalid."] }, { "name": "payable", @@ -623,9 +970,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -651,21 +996,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -681,251 +1020,187 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [u64] - The total payment for the gas amount." - ] + "arguments": [" * [u64] - The total payment for the gas amount."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, { "inputs": [ { - "name": "domain", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - }, - { - "name": "gas_oracle", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "name": "beneficiary", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" } ], - "name": "set_gas_oracle", + "name": "set_beneficiary", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", "arguments": [ - " Sets the gas oracle for a domain." - ] - }, - { - "name": "doc-comment", - "arguments": [ - "" + " Sets the beneficiary to `beneficiary`. Only callable by the owner." ] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - " * `domain`: [u32] - The domain to set the gas oracle for." - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `gas_oracle`: [b256] - The gas oracle." - ] + "arguments": [" * `beneficiary`: [Identity] - The new beneficiary."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [" * If the caller is not the owner."] }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, { - "inputs": [], - "name": "beneficiary", - "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", - "attributes": [ + "inputs": [ { - "name": "doc-comment", - "arguments": [ - " Gets the current beneficiary." - ] + "name": "domain", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a" }, { - "name": "doc-comment", - "arguments": [ - "" - ] - }, + "name": "config", + "concreteTypeId": "72e5e46f1e7d3f8964a9236d110d456cb86fea809e436c91f60e6503b65f9f1d" + } + ], + "name": "set_destination_gas_config", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" Sets the gas configs for a destination domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [Identity] - The beneficiary." - ] + "arguments": [" ### Arguments"] }, { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [], - "name": "claim", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ + "name": "doc-comment", + "arguments": [""] + }, { "name": "doc-comment", "arguments": [ - " Sends all base asset funds to the beneficiary. Callable by anyone." + " * `domain`: [Vec] - The domains to set the gas config for." ] }, { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " * `config`: [Vec] - The gas config to set." ] + }, + { + "name": "storage", + "arguments": ["read", "write"] } ] }, { "inputs": [ { - "name": "beneficiary", - "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ], - "name": "set_beneficiary", + "name": "set_gas_oracle", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", - "arguments": [ - " Sets the beneficiary to `beneficiary`. Only callable by the owner." - ] + "arguments": [" Sets the gas oracle for a domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * `beneficiary`: [Identity] - The new beneficiary." + " * `domain`: [u32] - The domain to set the gas oracle for." ] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" * `gas_oracle`: [b256] - The gas oracle."] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the caller is not the owner."] }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -941,10 +1216,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -955,9 +1227,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -968,9 +1238,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -981,10 +1249,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -1000,9 +1265,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -1013,68 +1276,50 @@ "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" } ], - "name": "get_gas_oracle", - "output": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "name": "gas_overhead", + "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", "attributes": [ { "name": "doc-comment", - "arguments": [ - " Gets the gas oracle for a given domain." - ] + "arguments": [" Gets the gas overhead for a given domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * `domain`: [u32] - The domain to get the gas oracle for." + " * `domain`: [u32] - The domain to get the gas overhead for." ] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [b256] - The gas oracle." - ] + "arguments": [" * [u64] - The gas overhead."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1085,242 +1330,343 @@ "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" }, { - "name": "gas_oracle", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "name": "gas_overhead", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } ], - "name": "set_gas_from_oracle", + "name": "set_gas_overhead", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", - "arguments": [ - " Sets the gas oracle for a given domain." - ] + "arguments": [" Sets the gas overhead for a given domain."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * `domain`: [u32] - The domain to set the gas oracle for." + " * `domain`: [u32] - The domain to set the gas overhead for." ] }, { "name": "doc-comment", - "arguments": [ - " * `gas_oracle`: [b256] - The gas oracle." - ] + "arguments": [" * `gas_overhead`: [u64] - The gas overhead."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [" * If the caller is not the owner."] }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] + } + ] + }, + { + "inputs": [], + "name": "hook_type", + "output": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Returns an enum that represents the type of hook"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [PostDispatchHookType] - The type of the hook."] } ] }, { "inputs": [ { - "name": "domain", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" } ], - "name": "gas_overhead", - "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "name": "post_dispatch", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { "name": "doc-comment", "arguments": [ - " Gets the gas overhead for a given domain." + " Manages payments on a source chain to cover gas costs of relaying" ] }, { "name": "doc-comment", "arguments": [ - "" + " messages to destination chains and includes the gas overhead per destination" ] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - "" + " The intended use of this contract is to store overhead gas amounts for destination" ] }, { "name": "doc-comment", "arguments": [ - " * `domain`: [u32] - The domain to get the gas overhead for." + " domains, e.g. Mailbox and ISM gas usage, such that users of this IGP are only required" ] }, { "name": "doc-comment", "arguments": [ - "" + " to specify the gas amount used by their own applications." ] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * [u64] - The gas overhead." + " * `metadata`: [Bytes] - The metadata required for the hook." ] }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message being dispatched."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the contract is not initialized."] + }, + { + "name": "doc-comment", + "arguments": [" * If the message is invalid"] + }, + { + "name": "doc-comment", + "arguments": [" * If IGP call fails"] + }, + { + "name": "doc-comment", + "arguments": [" * If metadata is invalid"] + }, + { + "name": "payable", + "arguments": [] + }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read", "write"] } ] }, { "inputs": [ { - "name": "domain", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" }, { - "name": "gas_overhead", - "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" } ], - "name": "set_gas_overhead", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "name": "quote_dispatch", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", "attributes": [ { "name": "doc-comment", "arguments": [ - " Sets the gas overhead for a given domain." + " Compute the payment required by the postDispatch call" ] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * `domain`: [u32] - The domain to set the gas overhead for." + " * `metadata`: [Bytes] - The metadata required for the hook." ] }, { "name": "doc-comment", - "arguments": [ - " * `gas_overhead`: [u64] - The gas overhead." - ] + "arguments": [" * `message`: [Bytes] - The message being dispatched."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", "arguments": [ - " * If the caller is not the owner." + " * [u64] - The payment required for the postDispatch call." ] }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the contract is not initialized."] + }, + { + "name": "doc-comment", + "arguments": [" * If the message is invalid"] + }, + { + "name": "doc-comment", + "arguments": [" * If IGP call fails"] + }, + { + "name": "doc-comment", + "arguments": [" * If metadata is invalid"] + }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "supports_metadata", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Returns whether the hook supports metadata"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `metadata`: [Bytes] - The metadata to be checked."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [bool] - Whether the hook supports the metadata."] } ] } ], "loggedTypes": [ { - "logId": "6817205463125046009", - "concreteTypeId": "5e9b943fe66bb2f9186016140592021f71cf98395bd3c80eef479a17a9b39e2b" + "logId": "17733344961923408823", + "concreteTypeId": "f6197f499ee863b7f79af9d4149ec4c76ac1f12af5d55ac5a3e9aa2adf195bc9" }, { "logId": "2161305517876418151", @@ -1330,29 +1676,33 @@ "logId": "16280289466020123285", "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" }, + { + "logId": "16783799790628909358", + "concreteTypeId": "e8ec08fc35b6312eaeca1be8ba0645b2eb1bf5656f53fed618eda7c184a7c6bc" + }, { "logId": "10098701174489624218", "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" }, { - "logId": "6336962848364594715", - "concreteTypeId": "57f16a22cb9e861b379fae117dc32f53512234a762ed50564496dff7600646b9" + "logId": "10230767756512909948", + "concreteTypeId": "8dfafd11d278da7cc3347b4432a7bd4dbb4dbc21d2475f98b8ae17b0a1a5c122" }, { "logId": "4571204900286667806", "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" }, { - "logId": "16331791483177302601", - "concreteTypeId": "e2a62dd30c887a49893c650f8f85200415866051cadc94f195537b3798498065" + "logId": "2494886949245166728", + "concreteTypeId": "229f9e763c8424886a0b828eb92ecd7ee7ee60fb9b34ec5595a43cc02b21a6e7" }, { - "logId": "7768365254202492752", - "concreteTypeId": "6bcec70a463a07509f86d07955802bee953038650739d9b15f8ba95a0e2052aa" + "logId": "13309401912119598731", + "concreteTypeId": "b8b47e85d8cb1e8bd7a47922d6ac2c9aef8c272feb8d5a404e972bb189aeedb3" }, { - "logId": "2943813761337727923", - "concreteTypeId": "28da8704d9711bb3e5ae8de91a1339201b6e3a044065e47395c1f4064d8e07d8" + "logId": "11141065444317510187", + "concreteTypeId": "9a9d03fe63ecba2bda69c30f8c743b0d5719d4dc01ad2cbbedce34332ae57970" }, { "logId": "4883303303013154842", @@ -1364,5 +1714,21 @@ } ], "messagesTypes": [], - "configurables": [] -} \ No newline at end of file + "configurables": [ + { + "name": "BASE_ASSET_DECIMALS", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 58712 + }, + { + "name": "TOKEN_EXCHANGE_RATE_SCALE", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 58728 + }, + { + "name": "DEFAULT_GAS_AMOUNT", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 58720 + } + ] +} diff --git a/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json b/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json index 2079ef84e3..eceda68c10 100644 --- a/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/InterchainSecurityModule.abi.json @@ -1,346 +1,619 @@ { - "programType": "contract", - "specVersion": "1", - "encodingVersion": "1", - "concreteTypes": [ - { - "type": "()", - "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "type": "(struct std::vec::Vec, u8)", - "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", - "metadataTypeId": 0 - }, - { - "type": "bool", - "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" - }, - { - "type": "enum MessageIdMultisigError", - "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e", - "metadataTypeId": 2 - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "metadataTypeId": 3 - }, - { - "type": "struct std::bytes::Bytes", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 6 - }, - { - "type": "struct std::vm::evm::evm_address::EvmAddress", - "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", - "metadataTypeId": 10 - }, - { - "type": "u32", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - }, - { - "type": "u8", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "metadataTypes": [ - { - "type": "(_, _)", - "metadataTypeId": 0, - "components": [ - { - "name": "__tuple_element", - "typeId": 9, - "typeArguments": [ - { - "name": "", - "typeId": 10 - } - ] - }, - { - "name": "__tuple_element", - "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ] - }, - { - "type": "b256", - "metadataTypeId": 1 - }, - { - "type": "enum MessageIdMultisigError", - "metadataTypeId": 2, - "components": [ - { - "name": "NoMultisigThreshold", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NoValidatorMatch", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "FailedToRecoverSigner", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "FailedToRecoverSignature", - "typeId": 6 - } - ] - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "metadataTypeId": 3, - "components": [ - { - "name": "UNUSED", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "ROUTING", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "AGGREGATION", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "LEGACY_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MERKLE_ROOT_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "MESSAGE_ID_MULTISIG", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NULL", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "CCIP_READ", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - } - ] - }, - { - "type": "generic T", - "metadataTypeId": 4 - }, - { - "type": "raw untyped ptr", - "metadataTypeId": 5 - }, - { - "type": "struct std::bytes::Bytes", - "metadataTypeId": 6, - "components": [ - { - "name": "buf", - "typeId": 7 - }, - { - "name": "len", - "typeId": 11 - } - ] - }, - { - "type": "struct std::bytes::RawBytes", - "metadataTypeId": 7, - "components": [ - { - "name": "ptr", - "typeId": 5 - }, - { - "name": "cap", - "typeId": 11 - } - ] - }, - { - "type": "struct std::vec::RawVec", - "metadataTypeId": 8, - "components": [ - { - "name": "ptr", - "typeId": 5 - }, - { - "name": "cap", - "typeId": 11 - } - ], - "typeParameters": [ - 4 - ] - }, - { - "type": "struct std::vec::Vec", - "metadataTypeId": 9, - "components": [ - { - "name": "buf", - "typeId": 8, - "typeArguments": [ - { - "name": "", - "typeId": 4 - } - ] - }, - { - "name": "len", - "typeId": 11 - } - ], - "typeParameters": [ - 4 - ] - }, - { - "type": "struct std::vm::evm::evm_address::EvmAddress", - "metadataTypeId": 10, - "components": [ - { - "name": "bits", - "typeId": 1 - } - ] - }, - { - "type": "u64", - "metadataTypeId": 11 - } - ], - "functions": [ - { - "inputs": [], - "name": "module_type", - "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "attributes": null - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "verify", - "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "digest", - "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "attributes": null - }, - { - "inputs": [ - { - "name": "metadata", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - }, - { - "name": "index", - "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - } - ], - "name": "signature_at", - "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "attributes": null - }, - { - "inputs": [ - { - "name": "message", - "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" - } - ], - "name": "validators_and_threshold", - "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", - "attributes": [ - { - "name": "storage", - "arguments": [ - "read" - ] - } - ] - }, - { - "inputs": [ - { - "name": "validator", - "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" - } - ], - "name": "enroll_validator", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - }, - { - "inputs": [ - { - "name": "threshold", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ], - "name": "set_threshold", - "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", - "attributes": [ - { - "name": "storage", - "arguments": [ - "write" - ] - } - ] - } - ], - "loggedTypes": [ - { - "logId": "12857203263801679462", - "concreteTypeId": "b26df63f7fe45e66396591c39fb75f64137b4d59aa8819e1543fd0bb06cd804e" - } - ], - "messagesTypes": [], - "configurables": [] - } \ No newline at end of file + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MessageIdMultisigError", + "concreteTypeId": "9208f06dcce9a0ccc70f9b9fe484e92b27fb8403737c88adef7279d81fdcc7fe", + "metadataTypeId": 3 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 6 + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 10 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 10 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 2, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MessageIdMultisigError", + "metadataTypeId": 3, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 6 + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 4 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 5 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 6, + "components": [ + { + "name": "buf", + "typeId": 7 + }, + { + "name": "len", + "typeId": 11 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 7, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 8, + "components": [ + { + "name": "ptr", + "typeId": 5 + }, + { + "name": "cap", + "typeId": 11 + } + ], + "typeParameters": [4] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 9, + "components": [ + { + "name": "buf", + "typeId": 8, + "typeArguments": [ + { + "name": "", + "typeId": 4 + } + ] + }, + { + "name": "len", + "typeId": 11 + } + ], + "typeParameters": [4] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 11 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [ModuleType] - The type of security model."] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Verifies the message using the metadata."] + }, + { + "name": "doc-comment", + "arguments": [ + " Assumes the signatures are in the same order as the validators." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message to be verified."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the threshold is not set or is less than 0."] + }, + { + "name": "doc-comment", + "arguments": [" * If the signature recovery fails."] + }, + { + "name": "doc-comment", + "arguments": [" * If the signer recovery fails."] + }, + { + "name": "doc-comment", + "arguments": [" * If no validator matches the signer."] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "digest", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the digest to be used for signature verification." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `metadata`: [Bytes] - ABI encoded module metadata."] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - Formatted Hyperlane message."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [Bytes] - The digest to be signed by validators."] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "index", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "signature_at", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the signature at a given index from the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `metadata`: [Bytes] - ABI encoded module metadata."] + }, + { + "name": "doc-comment", + "arguments": [ + " * `index`: [u32] - The index of the signature to be retrieved." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [Bytes] - Packed encoding of signature (65 bytes)."] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "validators_and_threshold", + "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the validators and threshold for the Multisig ISM for the given message." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message to be processed."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of validators that are set to approve the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u8] - The threshold of approval for the Multisig ISM." + ] + }, + { + "name": "storage", + "arguments": ["read"] + } + ] + }, + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + } + ], + "name": "enroll_validator", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Enrolls a validator to the Multisig ISM."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validator`: [EvmAddress] - The address of the validator to be enrolled." + ] + }, + { + "name": "storage", + "arguments": ["write"] + } + ] + }, + { + "inputs": [ + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "set_threshold", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Sets the threshold for the Multisig ISM."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * `threshold`: [u8] - The threshold of approval for the Multisig ISM." + ] + }, + { + "name": "storage", + "arguments": ["write"] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "10522924883731128524", + "concreteTypeId": "9208f06dcce9a0ccc70f9b9fe484e92b27fb8403737c88adef7279d81fdcc7fe" + } + ], + "messagesTypes": [], + "configurables": [] +} diff --git a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json index 38f1a37097..e4ba2f1b96 100644 --- a/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/Mailbox.abi.json @@ -16,8 +16,8 @@ "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "type": "enum MailboxError", - "concreteTypeId": "440e9980d3bd496a07b9348ba2cc9553c25410fe4a1c251d8303bc073ca3c472", + "type": "enum interfaces::mailbox::mailbox::MailboxError", + "concreteTypeId": "68180f8a59a30ee2f3461d64d15269bb1789948b3138b259046029f86c0b23a1", "metadataTypeId": 0 }, { @@ -121,7 +121,7 @@ ], "metadataTypes": [ { - "type": "enum MailboxError", + "type": "enum interfaces::mailbox::mailbox::MailboxError", "metadataTypeId": 0, "components": [ { @@ -148,10 +148,6 @@ "name": "MessageVerificationFailed", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, - { - "name": "AlreadyInitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, { "name": "MessageTooLarge", "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" @@ -433,27 +429,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Gets the default hook used for message verification." - ] + "arguments": [" Gets the default hook used for message verification."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -463,9 +451,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -476,39 +462,27 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Gets the default ISM used for message verification." - ] + "arguments": [" Gets the default ISM used for message verification."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [ContractId] - Address implementing ISM interface." - ] + "arguments": [" * [ContractId] - Address implementing ISM interface."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -524,27 +498,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns true if the message has been processed." - ] + "arguments": [" Returns true if the message has been processed."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -554,33 +520,23 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [bool] - True if the message has been processed." - ] + "arguments": [" * [bool] - True if the message has been processed."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -618,27 +574,19 @@ }, { "name": "doc-comment", - "arguments": [ - " Returns the message's ID." - ] + "arguments": [" Returns the message's ID."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -666,75 +614,51 @@ }, { "name": "doc-comment", - "arguments": [ - " * `hook`: [ContractId] - The hook contract Id." - ] + "arguments": [" * `hook`: [ContractId] - The hook contract Id."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [b256] - The ID of the dispatched message." - ] + "arguments": [" * [b256] - The ID of the dispatched message."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the message body is too large." - ] + "arguments": [" * If the message body is too large."] }, { "name": "doc-comment", - "arguments": [ - " * If the contract is paused." - ] + "arguments": [" * If the contract is paused."] }, { "name": "doc-comment", - "arguments": [ - " * If reentrancy is detected." - ] + "arguments": [" * If reentrancy is detected."] }, { "name": "doc-comment", - "arguments": [ - " * If any external call fails." - ] + "arguments": [" * If any external call fails."] }, { "name": "payable", @@ -742,10 +666,7 @@ }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -753,7 +674,7 @@ "inputs": [ { "name": "owner", - "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" }, { "name": "default_ism", @@ -773,33 +694,23 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Initializes the contract." - ] + "arguments": [" Initializes the contract."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `owner`: [b256] - The owner of the contract." - ] + "arguments": [" * `owner`: [Identity] - The owner of the contract."] }, { "name": "doc-comment", @@ -821,33 +732,23 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the contract is already initialized." - ] + "arguments": [" * If the contract is already initialized."] }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -858,39 +759,27 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the ID of the last dispatched message." - ] + "arguments": [" Returns the ID of the last dispatched message."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [b256] - The ID of the last dispatched message." - ] + "arguments": [" * [b256] - The ID of the last dispatched message."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -907,27 +796,19 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [u32] - The domain of the contract." - ] + "arguments": [" * [u32] - The domain of the contract."] } ] }, @@ -944,33 +825,23 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [u32] - The number of leaves in the merkle tree." - ] + "arguments": [" * [u32] - The number of leaves in the merkle tree."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -990,27 +861,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Processes a message." - ] + "arguments": [" Processes a message."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1026,70 +889,47 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the contract is paused." - ] + "arguments": [" * If the contract is paused."] }, { "name": "doc-comment", - "arguments": [ - " * If reentrancy is detected." - ] + "arguments": [" * If reentrancy is detected."] }, { "name": "doc-comment", - "arguments": [ - " * If the message has already been delivered." - ] + "arguments": [" * If the message has already been delivered."] }, { "name": "doc-comment", - "arguments": [ - " * If the message's protocol version is invalid." - ] + "arguments": [" * If the message's protocol version is invalid."] }, { "name": "doc-comment", - "arguments": [ - " * If the message's origin is invalid." - ] + "arguments": [" * If the message's origin is invalid."] }, { "name": "doc-comment", - "arguments": [ - " * If the message's verification fails." - ] + "arguments": [" * If the message's verification fails."] }, { "name": "doc-comment", - "arguments": [ - " * If any external call fails." - ] + "arguments": [" * If any external call fails."] }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -1121,27 +961,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Quotes a price for dispatching a message" - ] + "arguments": [" Quotes a price for dispatching a message"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1169,63 +1001,43 @@ }, { "name": "doc-comment", - "arguments": [ - " * `hook`: [ContractId] - The hook contract Id." - ] + "arguments": [" * `hook`: [ContractId] - The hook contract Id."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [u64] - The price of the dispatch." - ] + "arguments": [" * [u64] - The price of the dispatch."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If any external call fails." - ] + "arguments": [" * If any external call fails."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1241,27 +1053,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the ISM set by a recipient." - ] + "arguments": [" Returns the ISM set by a recipient."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1271,57 +1075,39 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [ContractId] - The ISM contract Id." - ] + "arguments": [" * [ContractId] - The ISM contract Id."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If recipient call fails." - ] + "arguments": [" * If recipient call fails."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1338,21 +1124,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1362,9 +1142,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1386,21 +1164,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1410,39 +1182,27 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [" * If the caller is not the owner."] }, { "name": "doc-comment", - "arguments": [ - " * If the provided hook address is zero." - ] + "arguments": [" * If the provided hook address is zero."] }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -1458,27 +1218,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Sets the default ISM used for message verification." - ] + "arguments": [" Sets the default ISM used for message verification."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1488,40 +1240,27 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [" * If the caller is not the owner."] }, { "name": "doc-comment", - "arguments": [ - " * If the provided ISM address is zero." - ] + "arguments": [" * If the provided ISM address is zero."] }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -1543,21 +1282,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -1567,39 +1300,27 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the caller is not the owner." - ] + "arguments": [" * If the caller is not the owner."] }, { "name": "doc-comment", - "arguments": [ - " * If the provided hook address is zero." - ] + "arguments": [" * If the provided hook address is zero."] }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -1610,9 +1331,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1623,9 +1342,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -1636,9 +1353,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -1654,10 +1369,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -1668,9 +1380,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1681,9 +1391,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -1694,10 +1402,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -1713,9 +1418,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] } @@ -1730,8 +1433,8 @@ "concreteTypeId": "8b3afcadf894415a10b09fc3717487e33802c8ffbb030edafe84ca4a71b280bc" }, { - "logId": "4904025822840310122", - "concreteTypeId": "440e9980d3bd496a07b9348ba2cc9553c25410fe4a1c251d8303bc073ca3c472" + "logId": "7500762266269322978", + "concreteTypeId": "68180f8a59a30ee2f3461d64d15269bb1789948b3138b259046029f86c0b23a1" }, { "logId": "16070551783826937832", @@ -1787,7 +1490,7 @@ { "name": "LOCAL_DOMAIN", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 56264 + "offset": 56136 } ] -} \ No newline at end of file +} diff --git a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json index 7f123f9b3e..c54f150354 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MerkleTreeHook.abi.json @@ -26,13 +26,13 @@ "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", - "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5", + "type": "enum interfaces::hooks::merkle_tree_hook::MerkleTreeHookError", + "concreteTypeId": "426dfda92f184fcf45cda17321259db8a156eaf4feb660630f639da630463334", "metadataTypeId": 2 }, { - "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", - "concreteTypeId": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "concreteTypeId": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", "metadataTypeId": 3 }, { @@ -41,8 +41,8 @@ "metadataTypeId": 4 }, { - "type": "struct interfaces::merkle_tree_hook::InsertedIntoTreeEvent", - "concreteTypeId": "3effa20b4d80bbc5778de2fd83fda27778f7cda3c122fe2120a4d3298509abcc", + "type": "struct interfaces::hooks::merkle_tree_hook::InsertedIntoTreeEvent", + "concreteTypeId": "d2f65b9b35997bd4c25ba60c8fdfc379fb7277a88e621b81804e37ee727dee7b", "metadataTypeId": 7 }, { @@ -99,7 +99,7 @@ ] }, { - "type": "enum interfaces::merkle_tree_hook::MerkleTreeError", + "type": "enum interfaces::hooks::merkle_tree_hook::MerkleTreeHookError", "metadataTypeId": 2, "components": [ { @@ -121,7 +121,7 @@ ] }, { - "type": "enum interfaces::post_dispatch_hook::PostDispatchHookType", + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", "metadataTypeId": 3, "components": [ { @@ -189,7 +189,7 @@ "metadataTypeId": 6 }, { - "type": "struct interfaces::merkle_tree_hook::InsertedIntoTreeEvent", + "type": "struct interfaces::hooks::merkle_tree_hook::InsertedIntoTreeEvent", "metadataTypeId": 7, "components": [ { @@ -273,9 +273,7 @@ "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } ], - "typeParameters": [ - 5 - ] + "typeParameters": [5] }, { "type": "struct std::vec::Vec", @@ -296,9 +294,7 @@ "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" } ], - "typeParameters": [ - 5 - ] + "typeParameters": [5] } ], "functions": [ @@ -309,39 +305,27 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the count from the MerkleTree." - ] + "arguments": [" Returns the count from the MerkleTree."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [u32] - The count from the MerkleTree." - ] + "arguments": [" * [u32] - The count from the MerkleTree."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -352,39 +336,27 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Gets the stored count of the MerkleTree." - ] + "arguments": [" Gets the stored count of the MerkleTree."] }, { "name": "doc-comment", - "arguments": [ - " And the current block number." - ] + "arguments": [" And the current block number."] }, { "name": "doc-comment", - "arguments": [ - " Used since we cannot query point in time data." - ] + "arguments": [" Used since we cannot query point in time data."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -394,9 +366,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -418,21 +388,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -442,33 +406,23 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the contract is already initialized." - ] + "arguments": [" * If the contract is already initialized."] }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -479,9 +433,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -492,39 +444,27 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the root from the MerkleTree." - ] + "arguments": [" Returns the root from the MerkleTree."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [b256] - The root from the MerkleTree." - ] + "arguments": [" * [b256] - The root from the MerkleTree."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -535,88 +475,58 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns the latest checkpoint from the MerkleTree." - ] + "arguments": [" Returns the latest checkpoint from the MerkleTree."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [b256] - The root from the MerkleTree." - ] + "arguments": [" * [b256] - The root from the MerkleTree."] }, { "name": "doc-comment", - "arguments": [ - " * [u32] - The count from the MerkleTree." - ] + "arguments": [" * [u32] - The count from the MerkleTree."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, { "inputs": [], "name": "hook_type", - "output": "92d375dbe21d8ba43fcbaa7f70e70c94baee06743f2d11d49bbe4fb8785becff", + "output": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns an enum that represents the type of hook" - ] + "arguments": [" Returns an enum that represents the type of hook"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [PostDispatchHookType] - The type of the hook." - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] + "arguments": [" * [PostDispatchHookType] - The type of the hook."] } ] }, @@ -648,21 +558,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -672,45 +576,31 @@ }, { "name": "doc-comment", - "arguments": [ - " * `message`: [Bytes] - The message to be processed." - ] + "arguments": [" * `message`: [Bytes] - The message to be processed."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the contract is not initialized." - ] + "arguments": [" * If the contract is not initialized."] }, { "name": "doc-comment", - "arguments": [ - " * If the message ID is not the latest dispatched ID." - ] + "arguments": [" * If the message ID is not the latest dispatched ID."] }, { "name": "doc-comment", - "arguments": [ - " * If there was assets sent with the function call." - ] + "arguments": [" * If there was assets sent with the function call."] }, { "name": "payable", @@ -718,10 +608,7 @@ }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -747,21 +634,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -771,27 +652,19 @@ }, { "name": "doc-comment", - "arguments": [ - " * `message`: [Bytes] - The message to be processed." - ] + "arguments": [" * `message`: [Bytes] - The message to be processed."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -801,9 +674,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -819,81 +690,57 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns whether the hook supports metadata" - ] + "arguments": [" Returns whether the hook supports metadata"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `metadata`: [Bytes] - The metadata to be checked." - ] + "arguments": [" * `metadata`: [Bytes] - The metadata to be checked."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [bool] - Whether the hook supports the metadata." - ] - }, - { - "name": "storage", - "arguments": [ - "read" - ] + "arguments": [" * [bool] - Whether the hook supports the metadata."] } ] } ], "loggedTypes": [ { - "logId": "6057534559405907588", - "concreteTypeId": "5410af966c0a9e8479bc59d683495479f235475d5ba3ac58c55b46d7e508aab5" + "logId": "4786760882046128079", + "concreteTypeId": "426dfda92f184fcf45cda17321259db8a156eaf4feb660630f639da630463334" }, { "logId": "15984911484641280648", "concreteTypeId": "ddd5d04db81b028838a7ccd28dd2d24122ce431e475b353a1d076c740b9168cb" }, { - "logId": "4539525118841371589", - "concreteTypeId": "3effa20b4d80bbc5778de2fd83fda27778f7cda3c122fe2120a4d3298509abcc" + "logId": "15201438314412997588", + "concreteTypeId": "d2f65b9b35997bd4c25ba60c8fdfc379fb7277a88e621b81804e37ee727dee7b" } ], "messagesTypes": [], "configurables": [] -} \ No newline at end of file +} diff --git a/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json index 9859af060e..897a508f4f 100644 --- a/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/MultisigISM.abi.json @@ -17,13 +17,13 @@ "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "type": "enum MerkleRootMultisigError", - "concreteTypeId": "838f554c0502325db7a2eb625a0eb694105f5366eb11999093426c18433a2969", + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", "metadataTypeId": 2 }, { - "type": "enum interfaces::isms::ism::ModuleType", - "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "type": "enum interfaces::isms::multisig::multisig_ism::MerkleRootMultisigError", + "concreteTypeId": "a9e12ce5428a3a5e60ce6d80348e323f1da0b084f3ba9e8bbe8c226d85c72c8d", "metadataTypeId": 3 }, { @@ -71,66 +71,66 @@ "metadataTypeId": 1 }, { - "type": "enum MerkleRootMultisigError", + "type": "enum interfaces::isms::ism::ModuleType", "metadataTypeId": 2, "components": [ { - "name": "NoMultisigThreshold", + "name": "UNUSED", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "NoValidatorMatch", + "name": "ROUTING", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "FailedToRecoverSigner", + "name": "AGGREGATION", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "InvalidMerkleIndexMetadata", + "name": "LEGACY_MULTISIG", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "FailedToRecoverSignature", - "typeId": 6 - } - ] - }, - { - "type": "enum interfaces::isms::ism::ModuleType", - "metadataTypeId": 3, - "components": [ - { - "name": "UNUSED", + "name": "MERKLE_ROOT_MULTISIG", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "ROUTING", + "name": "MESSAGE_ID_MULTISIG", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "AGGREGATION", + "name": "NULL", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "LEGACY_MULTISIG", + "name": "CCIP_READ", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, + } + ] + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MerkleRootMultisigError", + "metadataTypeId": 3, + "components": [ { - "name": "MERKLE_ROOT_MULTISIG", + "name": "NoMultisigThreshold", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "MESSAGE_ID_MULTISIG", + "name": "NoValidatorMatch", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "NULL", + "name": "FailedToRecoverSigner", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" }, { - "name": "CCIP_READ", + "name": "InvalidMerkleIndexMetadata", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 6 } ] }, @@ -183,9 +183,7 @@ "typeId": 11 } ], - "typeParameters": [ - 4 - ] + "typeParameters": [4] }, { "type": "struct std::vec::Vec", @@ -206,9 +204,7 @@ "typeId": 11 } ], - "typeParameters": [ - 4 - ] + "typeParameters": [4] }, { "type": "struct std::vm::evm::evm_address::EvmAddress", @@ -245,27 +241,19 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [ModuleType] - The type of security model." - ] + "arguments": [" * [ModuleType] - The type of security model."] } ] }, @@ -285,27 +273,25 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Verifies the message using the metadata." - ] + "arguments": [" Verifies the message using the metadata."] }, { "name": "doc-comment", "arguments": [ - "" + " Assumes the signatures are in the same order as the validators." ] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] }, { "name": "doc-comment", @@ -315,27 +301,19 @@ }, { "name": "doc-comment", - "arguments": [ - " * `message`: [Bytes] - The message to be verified." - ] + "arguments": [" * `message`: [Bytes] - The message to be verified."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -345,51 +323,35 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the threshold is not set or is less than 0." - ] + "arguments": [" * If the threshold is not set or is less than 0."] }, { "name": "doc-comment", - "arguments": [ - " * If the signature recovery fails." - ] + "arguments": [" * If the signature recovery fails."] }, { "name": "doc-comment", - "arguments": [ - " * If the signer recovery fails." - ] + "arguments": [" * If the signer recovery fails."] }, { "name": "doc-comment", - "arguments": [ - " * If no validator matches the signer." - ] + "arguments": [" * If no validator matches the signer."] }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -415,75 +377,51 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `metadata`: [Bytes] - ABI encoded module metadata." - ] + "arguments": [" * `metadata`: [Bytes] - ABI encoded module metadata."] }, { "name": "doc-comment", - "arguments": [ - " * `message`: [Bytes] - Formatted Hyperlane message." - ] + "arguments": [" * `message`: [Bytes] - Formatted Hyperlane message."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [Bytes] - The digest to be signed by validators." - ] + "arguments": [" * [Bytes] - The digest to be signed by validators."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -493,9 +431,7 @@ }, { "name": "doc-comment", - "arguments": [ - " * If data passed in is invalid." - ] + "arguments": [" * If data passed in is invalid."] } ] }, @@ -521,27 +457,19 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `metadata`: [Bytes] - ABI encoded module metadata." - ] + "arguments": [" * `metadata`: [Bytes] - ABI encoded module metadata."] }, { "name": "doc-comment", @@ -551,27 +479,19 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [Bytes] - Packed encoding of signature (65 bytes)." - ] + "arguments": [" * [Bytes] - Packed encoding of signature (65 bytes)."] } ] }, @@ -593,45 +513,31 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `message`: [Bytes] - The message to be processed." - ] + "arguments": [" * `message`: [Bytes] - The message to be processed."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -647,9 +553,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -665,27 +569,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Enrolls a validator to the Multisig ISM." - ] + "arguments": [" Enrolls a validator to the Multisig ISM."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -695,9 +591,7 @@ }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] }, @@ -713,27 +607,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Sets the threshold for the Multisig ISM." - ] + "arguments": [" Sets the threshold for the Multisig ISM."] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -743,19 +629,17 @@ }, { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] } ], "loggedTypes": [ { - "logId": "9479889525628088925", - "concreteTypeId": "838f554c0502325db7a2eb625a0eb694105f5366eb11999093426c18433a2969" + "logId": "12241114625345206878", + "concreteTypeId": "a9e12ce5428a3a5e60ce6d80348e323f1da0b084f3ba9e8bbe8c226d85c72c8d" } ], "messagesTypes": [], "configurables": [] -} \ No newline at end of file +} diff --git a/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json b/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json index 26aea85f59..d06611e6c6 100644 --- a/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/RoutingISM.abi.json @@ -16,13 +16,13 @@ "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "type": "enum DomainRoutingIsmError", - "concreteTypeId": "d6a68e63771bcc70200ac9382eacbf6434843d6e1d95b91d3d4752aaa277bb50", + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", "metadataTypeId": 1 }, { - "type": "enum interfaces::isms::ism::ModuleType", - "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "type": "enum interfaces::isms::routing::default_fallback_domain_routing_ism::DefaultFallbackDomainRoutingIsmError", + "concreteTypeId": "f417349370c05301429c43a092123f2c779795b031cda28952bc772aa336c228", "metadataTypeId": 2 }, { @@ -101,31 +101,9 @@ } ] }, - { - "type": "enum DomainRoutingIsmError", - "metadataTypeId": 1, - "components": [ - { - "name": "AlreadyInitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "NotInitialized", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, - { - "name": "DomainModuleLengthMismatch", - "typeId": 0 - }, - { - "name": "DomainNotSet", - "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - } - ] - }, { "type": "enum interfaces::isms::ism::ModuleType", - "metadataTypeId": 2, + "metadataTypeId": 1, "components": [ { "name": "UNUSED", @@ -158,10 +136,16 @@ { "name": "CCIP_READ", "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" - }, + } + ] + }, + { + "type": "enum interfaces::isms::routing::default_fallback_domain_routing_ism::DefaultFallbackDomainRoutingIsmError", + "metadataTypeId": 2, + "components": [ { - "name": "ARB_L2_TO_L1", - "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + "name": "DomainModuleLengthMismatch", + "typeId": 0 } ] }, @@ -286,9 +270,7 @@ "typeId": 18 } ], - "typeParameters": [ - 7 - ] + "typeParameters": [7] }, { "type": "struct std::vec::Vec", @@ -309,9 +291,7 @@ "typeId": 18 } ], - "typeParameters": [ - 7 - ] + "typeParameters": [7] }, { "type": "struct sway_libs::ownership::events::OwnershipRenounced", @@ -357,7 +337,36 @@ "inputs": [], "name": "module_type", "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", - "attributes": null + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [ModuleType] - The type of security model."] + } + ] }, { "inputs": [ @@ -374,10 +383,68 @@ "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", "attributes": [ { - "name": "storage", + "name": "doc-comment", + "arguments": [" Verifies the message using the metadata."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", "arguments": [ - "read" + " * `metadata`: [Bytes] - The metadata to be used for verification." ] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - The message to be verified."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the ISM call fails."] + }, + { + "name": "storage", + "arguments": ["read"] } ] }, @@ -392,10 +459,46 @@ "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " Returns the ISM responsible for verifying the message." ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `message`: [Bytes] - Formatted Hyperlane message"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [b256] - The ISM to use to verify the message"] + }, + { + "name": "storage", + "arguments": ["read"] } ] }, @@ -404,11 +507,29 @@ "name": "domains", "output": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", "attributes": [ + { + "name": "doc-comment", + "arguments": [" Returns the domains that have been set"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [Vec] - The list of origin domains."] + }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -416,18 +537,59 @@ "inputs": [ { "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "mailbox", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" } ], "name": "initialize", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ + { + "name": "doc-comment", + "arguments": [" Sets the owner and mailbox of the ISM."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `owner`: [Identity] - The address of the owner."] + }, + { + "name": "doc-comment", + "arguments": [" * `mailbox`: [b256] - The address of the mailbox."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the ISM is already initialized."] + }, { "name": "storage", - "arguments": [ - "write", - "read" - ] + "arguments": ["write", "read"] } ] }, @@ -435,6 +597,10 @@ "inputs": [ { "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "mailbox", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" }, { @@ -450,11 +616,99 @@ "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { - "name": "storage", + "name": "doc-comment", + "arguments": [ + " Sets the ISMs to be used for the specified origin domains" + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `owner`: [Identity] - The address of the owner."] + }, + { + "name": "doc-comment", + "arguments": [" * `mailbox`: [b256] - The address of the mailbox."] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domains`: [Vec] - The list of origin domains." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `modules`: [Vec] - The list of ISMs to be used for the specified domains." + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the ISM is already initialized."] + }, + { + "name": "doc-comment", "arguments": [ - "write", - "read" + " * If the length of the domains and modules do not match." ] + }, + { + "name": "storage", + "arguments": ["write", "read"] + } + ] + }, + { + "inputs": [], + "name": "mailbox", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "doc-comment", + "arguments": [" Returns the fallback mailbox for the ISM"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * [b256] - The address of the mailbox."] + }, + { + "name": "storage", + "arguments": ["read"] } ] }, @@ -469,10 +723,48 @@ "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", "attributes": [ { - "name": "storage", + "name": "doc-comment", "arguments": [ - "read" + " Returns the ISM to be used for the specified origin domain" ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `domain`: [u32] - The origin domain."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Returns"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [ + " * [b256] - The ISM to be used for the specified domain." + ] + }, + { + "name": "storage", + "arguments": ["read"] } ] }, @@ -486,12 +778,49 @@ "name": "remove", "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ + { + "name": "doc-comment", + "arguments": [" Removes the specified origin domain"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `domain`: [u32] - The origin domain."] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the ISM is not initialized."] + }, + { + "name": "doc-comment", + "arguments": [" * If the caller is not the owner."] + }, { "name": "storage", - "arguments": [ - "write", - "read" - ] + "arguments": ["write", "read"] } ] }, @@ -510,11 +839,56 @@ "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", "attributes": [ { - "name": "storage", + "name": "doc-comment", + "arguments": [ + " Sets the ISM to be used for the specified origin domain" + ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Arguments"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * `domain`: [u32] - The origin domain."] + }, + { + "name": "doc-comment", "arguments": [ - "write", - "read" + " * `module`: [b256] - The ISM to be used for the specified domain." ] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" ### Reverts"] + }, + { + "name": "doc-comment", + "arguments": [""] + }, + { + "name": "doc-comment", + "arguments": [" * If the ISM is not initialized."] + }, + { + "name": "doc-comment", + "arguments": [" * If the caller is not the owner."] + }, + { + "name": "storage", + "arguments": ["write", "read"] } ] }, @@ -530,10 +904,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -544,9 +915,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -557,9 +926,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -570,10 +937,7 @@ "attributes": [ { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -589,18 +953,12 @@ "attributes": [ { "name": "storage", - "arguments": [ - "write" - ] + "arguments": ["write"] } ] } ], "loggedTypes": [ - { - "logId": "15467206528101764208", - "concreteTypeId": "d6a68e63771bcc70200ac9382eacbf6434843d6e1d95b91d3d4752aaa277bb50" - }, { "logId": "2161305517876418151", "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" @@ -609,6 +967,10 @@ "logId": "16280289466020123285", "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" }, + { + "logId": "17588584677575250689", + "concreteTypeId": "f417349370c05301429c43a092123f2c779795b031cda28952bc772aa336c228" + }, { "logId": "4571204900286667806", "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" @@ -624,4 +986,4 @@ ], "messagesTypes": [], "configurables": [] -} \ No newline at end of file +} diff --git a/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json b/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json index 8215973296..e4bab65bc4 100644 --- a/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json +++ b/rust/main/chains/hyperlane-fuel/abis/ValidatorAnnounce.abi.json @@ -3,11 +3,6 @@ "specVersion": "1", "encodingVersion": "1", "concreteTypes": [ - { - "type": "[u8; 32]", - "concreteTypeId": "c0cb0154daecd457849d890b38a00e4ebac52e820cb461e0477aaadee6919e1e", - "metadataTypeId": 1 - }, { "type": "b256", "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" @@ -17,34 +12,34 @@ "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" }, { - "type": "enum ValidatorAnnounceError", - "concreteTypeId": "6dea538ce06cc546aa65f360420bf2395788f6009094d96bedda53dc9e364178", - "metadataTypeId": 2 + "type": "enum interfaces::va::ValidatorAnnounceError", + "concreteTypeId": "ec76592f2dcf24ec6527242afd8946282ac000fffe21a0ed75a797cbf460a556", + "metadataTypeId": 1 }, { "type": "struct interfaces::va::ValidatorAnnouncementEvent", "concreteTypeId": "d99160a54786c91aa3bfabca957c17df96dbae05a4c79f958b3da89ddc751fbf", - "metadataTypeId": 5 + "metadataTypeId": 4 }, { "type": "struct std::bytes::Bytes", "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", - "metadataTypeId": 6 + "metadataTypeId": 5 }, { "type": "struct std::contract_id::ContractId", "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "metadataTypeId": 8 + "metadataTypeId": 7 }, { "type": "struct std::string::String", "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c", - "metadataTypeId": 9 + "metadataTypeId": 8 }, { "type": "struct std::vec::Vec", "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", - "metadataTypeId": 11, + "metadataTypeId": 10, "typeArguments": [ "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" ] @@ -52,7 +47,7 @@ { "type": "struct std::vec::Vec", "concreteTypeId": "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8", - "metadataTypeId": 11, + "metadataTypeId": 10, "typeArguments": [ "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" ] @@ -60,7 +55,7 @@ { "type": "struct std::vec::Vec>", "concreteTypeId": "356056ebd0caea5064f10ead20d08a92ad675e09e3fa875f9d632a675fdea875", - "metadataTypeId": 11, + "metadataTypeId": 10, "typeArguments": [ "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8" ] @@ -68,15 +63,11 @@ { "type": "struct std::vm::evm::evm_address::EvmAddress", "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", - "metadataTypeId": 12 + "metadataTypeId": 11 }, { "type": "u32", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" - }, - { - "type": "u8", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" } ], "metadataTypes": [ @@ -85,18 +76,8 @@ "metadataTypeId": 0 }, { - "type": "[_; 32]", + "type": "enum interfaces::va::ValidatorAnnounceError", "metadataTypeId": 1, - "components": [ - { - "name": "__array_element", - "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" - } - ] - }, - { - "type": "enum ValidatorAnnounceError", - "metadataTypeId": 2, "components": [ { "name": "ValidatorNotSigner", @@ -110,57 +91,57 @@ }, { "type": "generic T", - "metadataTypeId": 3 + "metadataTypeId": 2 }, { "type": "raw untyped ptr", - "metadataTypeId": 4 + "metadataTypeId": 3 }, { "type": "struct interfaces::va::ValidatorAnnouncementEvent", - "metadataTypeId": 5, + "metadataTypeId": 4, "components": [ { "name": "validator", - "typeId": 12 + "typeId": 11 }, { "name": "storage_location", - "typeId": 9 + "typeId": 8 } ] }, { "type": "struct std::bytes::Bytes", - "metadataTypeId": 6, + "metadataTypeId": 5, "components": [ { "name": "buf", - "typeId": 7 + "typeId": 6 }, { "name": "len", - "typeId": 13 + "typeId": 12 } ] }, { "type": "struct std::bytes::RawBytes", - "metadataTypeId": 7, + "metadataTypeId": 6, "components": [ { "name": "ptr", - "typeId": 4 + "typeId": 3 }, { "name": "cap", - "typeId": 13 + "typeId": 12 } ] }, { "type": "struct std::contract_id::ContractId", - "metadataTypeId": 8, + "metadataTypeId": 7, "components": [ { "name": "bits", @@ -170,57 +151,53 @@ }, { "type": "struct std::string::String", - "metadataTypeId": 9, + "metadataTypeId": 8, "components": [ { "name": "bytes", - "typeId": 6 + "typeId": 5 } ] }, { "type": "struct std::vec::RawVec", - "metadataTypeId": 10, + "metadataTypeId": 9, "components": [ { "name": "ptr", - "typeId": 4 + "typeId": 3 }, { "name": "cap", - "typeId": 13 + "typeId": 12 } ], - "typeParameters": [ - 3 - ] + "typeParameters": [2] }, { "type": "struct std::vec::Vec", - "metadataTypeId": 11, + "metadataTypeId": 10, "components": [ { "name": "buf", - "typeId": 10, + "typeId": 9, "typeArguments": [ { "name": "", - "typeId": 3 + "typeId": 2 } ] }, { "name": "len", - "typeId": 13 + "typeId": 12 } ], - "typeParameters": [ - 3 - ] + "typeParameters": [2] }, { "type": "struct std::vm::evm::evm_address::EvmAddress", - "metadataTypeId": 12, + "metadataTypeId": 11, "components": [ { "name": "bits", @@ -230,7 +207,7 @@ }, { "type": "u64", - "metadataTypeId": 13 + "metadataTypeId": 12 } ], "functions": [ @@ -254,33 +231,23 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Announces a validator signature storage location " - ] + "arguments": [" Announces a validator signature storage location "] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * `validator`: [b256] - The address of the validator" - ] + "arguments": [" * `validator`: [b256] - The address of the validator"] }, { "name": "doc-comment", @@ -296,51 +263,35 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * [bool] - Whether the announcement was successful" - ] + "arguments": [" * [bool] - Whether the announcement was successful"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Reverts" - ] + "arguments": [" ### Reverts"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " * If the announcement has already been made" - ] + "arguments": [" * If the announcement has already been made"] }, { "name": "doc-comment", @@ -350,10 +301,7 @@ }, { "name": "storage", - "arguments": [ - "read", - "write" - ] + "arguments": ["read", "write"] } ] }, @@ -369,27 +317,19 @@ "attributes": [ { "name": "doc-comment", - "arguments": [ - " Returns a list of all announced storage locations " - ] + "arguments": [" Returns a list of all announced storage locations "] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Arguments" - ] + "arguments": [" ### Arguments"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -399,9 +339,7 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] }, @@ -418,21 +356,15 @@ }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", - "arguments": [ - " ### Returns" - ] + "arguments": [" ### Returns"] }, { "name": "doc-comment", - "arguments": [ - "" - ] + "arguments": [""] }, { "name": "doc-comment", @@ -442,25 +374,15 @@ }, { "name": "storage", - "arguments": [ - "read" - ] + "arguments": ["read"] } ] } ], "loggedTypes": [ { - "logId": "7920234759210190150", - "concreteTypeId": "6dea538ce06cc546aa65f360420bf2395788f6009094d96bedda53dc9e364178" - }, - { - "logId": "13892198939516261463", - "concreteTypeId": "c0cb0154daecd457849d890b38a00e4ebac52e820cb461e0477aaadee6919e1e" - }, - { - "logId": "14454674236531057292", - "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + "logId": "17038904299369735404", + "concreteTypeId": "ec76592f2dcf24ec6527242afd8946282ac000fffe21a0ed75a797cbf460a556" }, { "logId": "15677418040839293210", @@ -472,12 +394,12 @@ { "name": "LOCAL_DOMAIN", "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", - "offset": 39256 + "offset": 38440 }, { "name": "MAILBOX_ID", "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", - "offset": 39264 + "offset": 38448 } ] -} \ No newline at end of file +} From bec5645f8b39485302402801255327409d435284 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 17:21:00 +0100 Subject: [PATCH 22/31] chore(fuel-indexer-events): generic event data transformer impl --- .../hyperlane-fuel/src/indexer/events.rs | 36 ++----------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/events.rs b/rust/main/chains/hyperlane-fuel/src/indexer/events.rs index 87fa417fb7..959ed40bf5 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer/events.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer/events.rs @@ -75,41 +75,11 @@ pub trait EventDataTransformer { Self: Sized; } -// Implement `EventDataTransformer` for `GasPaymentEvent` -impl EventDataTransformer for GasPaymentEvent { +impl EventDataTransformer for S { fn transform(self) -> T where - T: From + Into> + PartialEq + Send + Sync + Debug + 'static, - { - T::from(self) - } -} - -// Implement `EventDataTransformer` for `DispatchEvent` -impl EventDataTransformer for DispatchEvent { - fn transform(self) -> T - where - T: From + Into> + PartialEq + Send + Sync + Debug + 'static, - { - T::from(self) - } -} - -// Implement `EventDataTransformer` for `InsertedIntoTreeEvent` -impl EventDataTransformer for InsertedIntoTreeEvent { - fn transform(self) -> T - where - T: From + Into> + PartialEq + Send + Sync + Debug + 'static, - { - T::from(self) - } -} - -// Implement `EventDataTransformer` for `ProcessIdEvent` -impl EventDataTransformer for ProcessIdEvent { - fn transform(self) -> T - where - T: From + Into> + PartialEq + Send + Sync + Debug + 'static, + T: From + Into> + PartialEq + Send + Sync + Debug + 'static, + Self: Sized, { T::from(self) } From 3c753e721bfad899c6b6fac35fcb41000f1287d7 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 17:23:45 +0100 Subject: [PATCH 23/31] chore(comment): va -> igp comment update --- rust/main/chains/hyperlane-fuel/src/interchain_gas.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs index d5d3b54020..a9171a78d3 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_gas.rs @@ -26,7 +26,7 @@ pub struct FuelInterchainGasPaymaster { } impl FuelInterchainGasPaymaster { - /// Create a new fuel validator announce contract + /// Create a new fuel IGP contract interface pub async fn new( conf: &ConnectionConf, locator: ContractLocator<'_>, From bc69993190abe2e4f85526291403337ccbabc237 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 17:32:11 +0100 Subject: [PATCH 24/31] chore(comment): ism comment update --- .../chains/hyperlane-fuel/src/interchain_security_module.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs index b30c00527f..5e2e9efb6b 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -14,7 +14,7 @@ use hyperlane_core::{ RawHyperlaneMessage, H256, U256, }; -/// A reference to a AggregationIsm contract on some Fuel chain +/// A reference to an ISM contract on some Fuel chain #[derive(Debug)] pub struct FuelInterchainSecurityModule { contract: InterchainSecurityModuleContract, @@ -23,7 +23,7 @@ pub struct FuelInterchainSecurityModule { } impl FuelInterchainSecurityModule { - /// Create a new fuel validator announce contract + /// Create a new fuel ISM contract interface pub async fn new( conf: &ConnectionConf, locator: ContractLocator<'_>, From e9e419df8be847247c78faa5219f7b2d6fb4c939 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 17:36:06 +0100 Subject: [PATCH 25/31] fix(contract-calls): use default for determine missing contracts --- .../chains/hyperlane-fuel/src/interchain_security_module.rs | 2 +- rust/main/chains/hyperlane-fuel/src/mailbox.rs | 4 ++-- rust/main/chains/hyperlane-fuel/src/routing_ism.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs index 5e2e9efb6b..58a8f8af02 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -85,7 +85,7 @@ impl InterchainSecurityModule for FuelInterchainSecurityModule { Bytes(metadata.to_vec()), Bytes(RawHyperlaneMessage::from(message)), ) - .determine_missing_contracts(Some(10)) + .determine_missing_contracts(None) .await .map_err(ChainCommunicationError::from_other)? .simulate(Execution::Realistic) diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index de903840c3..1ea3359b44 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -162,7 +162,7 @@ impl Mailbox for FuelMailbox { ) .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum) .with_tx_policies(tx_policies) - .determine_missing_contracts(Some(10)) + .determine_missing_contracts(None) .await .map_err(ChainCommunicationError::from_other)? .call() @@ -214,7 +214,7 @@ impl Mailbox for FuelMailbox { Bytes(RawHyperlaneMessage::from(message)), ) .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum) - .determine_missing_contracts(Some(10)) + .determine_missing_contracts(None) .await .map_err(ChainCommunicationError::from_other)? .simulate(Execution::Realistic) diff --git a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs index 4b63553e24..62b9960a47 100644 --- a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs @@ -64,7 +64,7 @@ impl RoutingIsm for FuelRoutingIsm { self.contract .methods() .route(Bytes(message.to_vec())) - .determine_missing_contracts(Some(10)) + .determine_missing_contracts(None) .await .map_err(ChainCommunicationError::from_other)? .simulate(Execution::StateReadOnly) From 1e7be59109ae735f1844e7a987555f9980789230 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 17:58:44 +0100 Subject: [PATCH 26/31] chore(spelling): Receipt --- .../src/indexer/query/conversions.rs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs index da25b7cf3b..4c09c65512 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs @@ -3,16 +3,16 @@ use fuel_core_types::{ fuel_asm::{Instruction, Word}, fuel_tx::{PanicInstruction, PanicReason}, }; -use fuels::tx::Receipt as FuelRecepit; +use fuels::tx::Receipt as FuelReceipt; use super::{types::Receipt, ReceiptType}; // These conversions are the `From` implementations for converting the `Receipt` schema from the Fuels Rust SDK // since we cannot implement `From` for our custom Recipt schema on the `fuels::tx::Receipt` directly. -pub fn generate_receipt(schema: Receipt) -> Result { +pub fn generate_receipt(schema: Receipt) -> Result { Ok(match schema.receipt_type { - ReceiptType::Call => FuelRecepit::Call { + ReceiptType::Call => FuelReceipt::Call { id: schema.id.map(|id| id.into()).unwrap_or_default(), to: schema .to @@ -47,7 +47,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::Return => FuelRecepit::Return { + ReceiptType::Return => FuelReceipt::Return { id: schema.id.map(|id| id.into()).unwrap_or_default(), val: schema .val @@ -62,7 +62,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::ReturnData => FuelRecepit::ReturnData { + ReceiptType::ReturnData => FuelReceipt::ReturnData { id: schema.id.map(|id| id.into()).unwrap_or_default(), ptr: schema .ptr @@ -91,7 +91,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::Panic => FuelRecepit::Panic { + ReceiptType::Panic => FuelReceipt::Panic { id: schema.id.map(|id| id.into()).unwrap_or_default(), reason: { let reason = schema @@ -109,7 +109,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .into(), contract_id: schema.contract_id.map(Into::into), }, - ReceiptType::Revert => FuelRecepit::Revert { + ReceiptType::Revert => FuelReceipt::Revert { id: schema.id.map(|id| id.into()).unwrap_or_default(), ra: schema .ra @@ -124,7 +124,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::Log => FuelRecepit::Log { + ReceiptType::Log => FuelReceipt::Log { id: schema.id.map(|id| id.into()).unwrap_or_default(), ra: schema .ra @@ -151,7 +151,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::LogData => FuelRecepit::LogData { + ReceiptType::LogData => FuelReceipt::LogData { id: schema.id.map(|id| id.into()).unwrap_or_default(), ra: schema .ra @@ -188,7 +188,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::Transfer => FuelRecepit::Transfer { + ReceiptType::Transfer => FuelReceipt::Transfer { id: schema.id.map(|id| id.into()).unwrap_or_default(), to: schema .to @@ -211,7 +211,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::TransferOut => FuelRecepit::TransferOut { + ReceiptType::TransferOut => FuelReceipt::TransferOut { id: schema.id.map(|id| id.into()).unwrap_or_default(), to: schema .to_address @@ -234,7 +234,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::ScriptResult => FuelRecepit::ScriptResult { + ReceiptType::ScriptResult => FuelReceipt::ScriptResult { result: Word::from( schema .result @@ -246,7 +246,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("gas_used".to_string()))? .into(), }, - ReceiptType::MessageOut => FuelRecepit::MessageOut { + ReceiptType::MessageOut => FuelReceipt::MessageOut { sender: schema .sender .ok_or_else(|| MissingField("sender".to_string()))? @@ -278,7 +278,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .into(), ), }, - ReceiptType::Mint => FuelRecepit::Mint { + ReceiptType::Mint => FuelReceipt::Mint { sub_id: schema .sub_id .ok_or_else(|| MissingField("sub_id".to_string()))? @@ -297,7 +297,7 @@ pub fn generate_receipt(schema: Receipt) -> Result .ok_or_else(|| MissingField("is".to_string()))? .into(), }, - ReceiptType::Burn => FuelRecepit::Burn { + ReceiptType::Burn => FuelReceipt::Burn { sub_id: schema .sub_id .ok_or_else(|| MissingField("sub_id".to_string()))? From 04dac6f5fe8b6c9cf8719f2b425b1037b8abc064 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 18:44:53 +0100 Subject: [PATCH 27/31] chore(errors): make errors more verbose --- .../hyperlane-fuel/src/aggregation_ism.rs | 13 ++- .../src/interchain_security_module.rs | 33 ++++++- .../main/chains/hyperlane-fuel/src/mailbox.rs | 98 +++++++++++++++++-- .../hyperlane-fuel/src/merkle_tree_hook.rs | 44 ++++++++- .../chains/hyperlane-fuel/src/multisig_ism.rs | 8 +- .../chains/hyperlane-fuel/src/routing_ism.rs | 22 ++++- .../hyperlane-fuel/src/validator_announce.rs | 19 +++- 7 files changed, 214 insertions(+), 23 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs index e83acc4241..0a5b5c2677 100644 --- a/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/aggregation_ism.rs @@ -5,7 +5,7 @@ use crate::{ use async_trait::async_trait; use fuels::{ accounts::wallet::WalletUnlocked, - programs::calls::Execution, + programs::calls::{ContractDependency, Execution}, types::{bech32::Bech32ContractId, Bytes}, }; use hyperlane_core::{ @@ -68,7 +68,16 @@ impl AggregationIsm for FuelAggregationIsm { .modules_and_threshold(Bytes(message.to_vec())) .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read modules and threshold, for contract 0x{:?} - {:?}", + self.contract.id().hash, + e + ) + .as_str(), + ) + }) .map(|res| { let (modules, threshold) = res.value; let modules = modules.iter().map(|v| v.into_h256()).collect(); diff --git a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs index 58a8f8af02..9609b59b04 100644 --- a/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs +++ b/rust/main/chains/hyperlane-fuel/src/interchain_security_module.rs @@ -70,7 +70,16 @@ impl InterchainSecurityModule for FuelInterchainSecurityModule { .module_type() .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to get module type for ISM contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| IsmType(res.value).into()) } @@ -87,10 +96,28 @@ impl InterchainSecurityModule for FuelInterchainSecurityModule { ) .determine_missing_contracts(None) .await - .map_err(ChainCommunicationError::from_other)? + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to get contract dependencies for dry run verify for ISM contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })? .simulate(Execution::Realistic) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to dry run verify for ISM contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| Some(U256::from(res.gas_used))) } } diff --git a/rust/main/chains/hyperlane-fuel/src/mailbox.rs b/rust/main/chains/hyperlane-fuel/src/mailbox.rs index 1ea3359b44..8240218cc9 100644 --- a/rust/main/chains/hyperlane-fuel/src/mailbox.rs +++ b/rust/main/chains/hyperlane-fuel/src/mailbox.rs @@ -86,7 +86,16 @@ impl Mailbox for FuelMailbox { .simulate(Execution::StateReadOnly) .await .map(|r| r.value) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read nonce for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) } #[instrument(level = "debug", err, ret, skip(self))] @@ -98,7 +107,15 @@ impl Mailbox for FuelMailbox { .simulate(Execution::StateReadOnly) .await .map(|r| r.value) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read delivered status for message 0x{:?} - {:?}", + id, e + ) + .as_str(), + ) + }) } #[instrument(err, ret, skip(self))] @@ -110,7 +127,16 @@ impl Mailbox for FuelMailbox { .simulate(Execution::StateReadOnly) .await .map(|r| r.value.into_h256()) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read default ISM for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) } #[instrument(err, ret, skip(self))] @@ -124,7 +150,16 @@ impl Mailbox for FuelMailbox { .simulate(Execution::StateReadOnly) .await .map(|r| r.value.into_h256()) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read recipient ISM for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) } #[instrument(err, ret, skip(self))] @@ -164,10 +199,28 @@ impl Mailbox for FuelMailbox { .with_tx_policies(tx_policies) .determine_missing_contracts(None) .await - .map_err(ChainCommunicationError::from_other)? + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to determine missing contracts for process call of mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })? .call() .await - .map_err(ChainCommunicationError::from_other)?; + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to call process for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })?; // Extract transaction success from the receipts let success = call_res @@ -216,10 +269,28 @@ impl Mailbox for FuelMailbox { .with_variable_output_policy(VariableOutputPolicy::EstimateMinimum) .determine_missing_contracts(None) .await - .map_err(ChainCommunicationError::from_other)? + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to determine missing contracts for process cost estimation of mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })? .simulate(Execution::Realistic) .await - .map_err(ChainCommunicationError::from_other)?; + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read process call cost for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })?; Ok(TxCostEstimate { gas_limit: ((simulate_call.gas_used as f64 * GAS_ESTIMATE_MULTIPLIER) as u64).into(), @@ -286,7 +357,16 @@ impl SequenceAwareIndexer for FuelDispatchIndexer { .simulate(Execution::StateReadOnly) .await .map(|r| r.value) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to read nonce for mailbox contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|sequence| (Some(sequence), tip)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs index 11b2722b67..bb0c1d0221 100644 --- a/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs +++ b/rust/main/chains/hyperlane-fuel/src/merkle_tree_hook.rs @@ -69,7 +69,16 @@ impl MerkleTreeHook for FuelMerkleTreeHook { .tree() .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to fetch tree from MerkleTreeHook contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| { let merkle_tree = res.value; IncrementalMerkle { @@ -85,7 +94,16 @@ impl MerkleTreeHook for FuelMerkleTreeHook { .count() .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to fetch count from MerkleTreeHook contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| res.value) } @@ -95,7 +113,16 @@ impl MerkleTreeHook for FuelMerkleTreeHook { .latest_checkpoint() .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to fetch latest checkpoint from MerkleTreeHook contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| { let (root, count) = res.value; Checkpoint { @@ -160,7 +187,16 @@ impl SequenceAwareIndexer for FuelMerkleTreeHookIndexer { .count_and_block() .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to fetch count and block from MerkleTreeHook contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| { let (count, tip) = res.value; (Some(count), tip) diff --git a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs index eb8a615662..cfd6f3c0ea 100644 --- a/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/multisig_ism.rs @@ -69,7 +69,13 @@ impl MultisigIsm for FuelMultisigIsm { .validators_and_threshold(Bytes(message.to_vec())) .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str(format!( + "Failed to fetch validators and threshold from MultisigIsm contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ).as_str()) + }) .map(|res| (res.value.0.into_h256_vec(), res.value.1)) } } diff --git a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs index 62b9960a47..7667944bd2 100644 --- a/rust/main/chains/hyperlane-fuel/src/routing_ism.rs +++ b/rust/main/chains/hyperlane-fuel/src/routing_ism.rs @@ -66,10 +66,28 @@ impl RoutingIsm for FuelRoutingIsm { .route(Bytes(message.to_vec())) .determine_missing_contracts(None) .await - .map_err(ChainCommunicationError::from_other)? + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed derermine dependencies for routing using RoutingIsm contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })? .simulate(Execution::StateReadOnly) .await - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to route message using RoutingIsm contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + }) .map(|res| res.value.into_h256()) } } diff --git a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs index 9cfb00f10c..d461d19861 100644 --- a/rust/main/chains/hyperlane-fuel/src/validator_announce.rs +++ b/rust/main/chains/hyperlane-fuel/src/validator_announce.rs @@ -72,7 +72,13 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { .simulate(Execution::StateReadOnly) .await .map(|res| res.value) - .map_err(ChainCommunicationError::from_other) + .map_err(|e| { + ChainCommunicationError::from_other_str(format!( + "Failed to fetch announced storage locations from ValidatorAnnounce contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ).as_str()) + }) } async fn announce(&self, announcement: SignedType) -> ChainResult { @@ -87,7 +93,16 @@ impl ValidatorAnnounce for FuelValidatorAnnounce { ) .call() .await - .map_err(ChainCommunicationError::from_other)?; + .map_err(|e| { + ChainCommunicationError::from_other_str( + format!( + "Failed to announce validator in ValidatorAnnounce contract at 0x{:?} - {:?}", + self.contract.contract_id().hash, + e + ) + .as_str(), + ) + })?; // Extract transaction success from the receipts let success = call_res From 1eeffaf67135563549b473ce85d127384f25d061 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Fri, 31 Jan 2025 18:55:15 +0100 Subject: [PATCH 28/31] fix(clippy): resolve clippy errors --- .../src/indexer/query/conversions.rs | 2 +- rust/main/chains/hyperlane-fuel/src/provider.rs | 6 +++--- rust/main/hyperlane-base/src/settings/base.rs | 14 ++++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs index 4c09c65512..85b7eb3d5c 100644 --- a/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs +++ b/rust/main/chains/hyperlane-fuel/src/indexer/query/conversions.rs @@ -330,5 +330,5 @@ pub fn word_to_panic_instruction(val: Word) -> PanicInstruction { // Cast to truncate in order to remove the `reason` bits. let instruction = (val >> INSTR_OFFSET) as u32; let reason = PanicReason::from(reason_u8); - PanicInstruction::error(reason, instruction.into()) + PanicInstruction::error(reason, instruction) } diff --git a/rust/main/chains/hyperlane-fuel/src/provider.rs b/rust/main/chains/hyperlane-fuel/src/provider.rs index 421b716ba8..460db52bc4 100644 --- a/rust/main/chains/hyperlane-fuel/src/provider.rs +++ b/rust/main/chains/hyperlane-fuel/src/provider.rs @@ -105,7 +105,7 @@ impl HyperlaneProvider for FuelProvider { .get_transaction_by_id(&hash_parsed.0.into()) .await .map_err(|_| HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))? - .ok_or_else(|| HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))?; + .ok_or(HyperlaneProviderError::CouldNotFindTransactionByHash(*hash))?; let block_number = transaction.block_height.ok_or_else(|| { ChainCommunicationError::from_other_str( @@ -130,13 +130,13 @@ impl HyperlaneProvider for FuelProvider { .iter() .filter_map(|receipt| receipt.sender()) .next() - .map(|sender| H256::from_slice(&sender.as_slice())) + .map(|sender| H256::from_slice(sender.as_slice())) .unwrap_or(H256::zero()); let recipient = receipts .iter() .filter_map(|receipt| receipt.recipient()) .next() - .map(|recipient| H256::from_slice(&recipient.as_slice())); + .map(|recipient| H256::from_slice(recipient.as_slice())); let nonce = receipts .iter() .filter_map(|receipt| receipt.nonce()) diff --git a/rust/main/hyperlane-base/src/settings/base.rs b/rust/main/hyperlane-base/src/settings/base.rs index 1d6e021d88..e7c0d0e814 100644 --- a/rust/main/hyperlane-base/src/settings/base.rs +++ b/rust/main/hyperlane-base/src/settings/base.rs @@ -84,14 +84,12 @@ impl Settings { /// Check and warn if reorg period is set for FuelVM domains. pub fn check_fuel_reorg(&self) { - self.chains.values().into_iter().for_each(|conf| { - if conf.domain.domain_protocol() == HyperlaneDomainProtocol::Fuel { - if !conf.reorg_period.is_none() { - warn!( - "Reorg period is set for fuel domain {:?}. FuelVM chains are implemented with instant finality", - conf.domain - ); - } + self.chains.values().for_each(|conf| { + if conf.domain.domain_protocol() == HyperlaneDomainProtocol::Fuel && !conf.reorg_period.is_none() { + warn!( + "Reorg period is set for fuel domain {:?}. FuelVM chains are implemented with instant finality", + conf.domain + ); } }); } From 287e791c961818402be1336f0f2fa3f0e5898719 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Tue, 18 Feb 2025 17:51:00 +0100 Subject: [PATCH 29/31] feat(e2e): fuelvm e2e workflow --- .github/workflows/test.yml | 15 +- rust/main/Cargo.lock | 331 +-- .../m20230309_000001_create_table_domain.rs | 30 +- rust/main/hyperlane-core/src/chain.rs | 9 +- rust/main/utils/run-locally/Cargo.toml | 4 + rust/main/utils/run-locally/src/cosmos/mod.rs | 140 +- .../utils/run-locally/src/cosmos/types.rs | 107 - rust/main/utils/run-locally/src/fuel/abis.rs | 48 + .../main/utils/run-locally/src/fuel/deploy.rs | 290 +++ .../fuel-contracts/aggregation-ism-abi.json | 768 ++++++ .../aggregation-ism-storage_slots.json | 6 + .../fuel/fuel-contracts/aggregation-ism.bin | Bin 0 -> 33776 bytes .../domain-routing-ism-abi.json | 1107 +++++++++ .../domain-routing-ism-storage_slots.json | 1 + .../fuel-contracts/domain-routing-ism.bin | Bin 0 -> 39952 bytes .../fallback-domain-routing-hook-abi.json | 880 +++++++ ...ack-domain-routing-hook-storage_slots.json | 6 + .../fallback-domain-routing-hook.bin | Bin 0 -> 31352 bytes .../fuel/fuel-contracts/gas-oracle-abi.json | 625 +++++ .../gas-oracle-storage_slots.json | 1 + .../src/fuel/fuel-contracts/gas-oracle.bin | Bin 0 -> 23088 bytes .../fuel-contracts/gas-paymaster-abi.json | 2063 +++++++++++++++++ .../gas-paymaster-storage_slots.json | 10 + .../src/fuel/fuel-contracts/gas-paymaster.bin | Bin 0 -> 60128 bytes .../src/fuel/fuel-contracts/mailbox-abi.json | 1789 ++++++++++++++ .../fuel-contracts/mailbox-storage_slots.json | 22 + .../src/fuel/fuel-contracts/mailbox.bin | Bin 0 -> 49904 bytes .../fuel-contracts/merkle-tree-hook-abi.json | 887 +++++++ .../merkle-tree-hook-storage_slots.json | 10 + .../fuel/fuel-contracts/merkle-tree-hook.bin | Bin 0 -> 25912 bytes .../message-id-multisig-ism-abi.json | 763 ++++++ ...message-id-multisig-ism-storage_slots.json | 1 + .../message-id-multisig-ism.bin | Bin 0 -> 33896 bytes .../msg-recipient-test-abi.json | 158 ++ .../msg-recipient-test-storage_slots.json | 10 + .../fuel-contracts/msg-recipient-test.bin | Bin 0 -> 8168 bytes .../fuel/fuel-contracts/pausable-ism-abi.json | 560 +++++ .../pausable-ism-storage_slots.json | 1 + .../src/fuel/fuel-contracts/pausable-ism.bin | Bin 0 -> 16640 bytes .../validator-announce-abi.json | 456 ++++ .../validator-announce-storage_slots.json | 1 + .../fuel-contracts/validator-announce.bin | Bin 0 -> 38992 bytes rust/main/utils/run-locally/src/fuel/mod.rs | 430 ++++ rust/main/utils/run-locally/src/fuel/types.rs | 15 + rust/main/utils/run-locally/src/fuel/utils.rs | 1 + rust/main/utils/run-locally/src/invariants.rs | 2 + .../invariants/base_termination_invariants.rs | 113 + rust/main/utils/run-locally/src/main.rs | 2 + rust/main/utils/run-locally/src/types.rs | 165 ++ rust/main/utils/run-locally/src/utils.rs | 11 + 50 files changed, 11424 insertions(+), 414 deletions(-) create mode 100644 rust/main/utils/run-locally/src/fuel/abis.rs create mode 100644 rust/main/utils/run-locally/src/fuel/deploy.rs create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/mailbox-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/mailbox-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/mailbox.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/merkle-tree-hook-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/merkle-tree-hook-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/merkle-tree-hook.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/pausable-ism-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/pausable-ism-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/pausable-ism.bin create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-abi.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-storage_slots.json create mode 100644 rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce.bin create mode 100644 rust/main/utils/run-locally/src/fuel/mod.rs create mode 100644 rust/main/utils/run-locally/src/fuel/types.rs create mode 100644 rust/main/utils/run-locally/src/fuel/utils.rs create mode 100644 rust/main/utils/run-locally/src/invariants/base_termination_invariants.rs create mode 100644 rust/main/utils/run-locally/src/types.rs diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aefcb0d9a9..e66c1dbbf0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -213,7 +213,7 @@ jobs: strategy: fail-fast: false matrix: - e2e-type: [cosmwasm, non-cosmwasm] + e2e-type: [cosmwasm, fuel, non-cosmwasm] steps: - uses: actions/setup-node@v4 with: @@ -231,6 +231,12 @@ jobs: - name: setup rust uses: dtolnay/rust-toolchain@stable + - name: setup fuel toolchain + uses: FuelLabs/action-fuel-toolchain@v0.7.0 + if: matrix.e2e-type == 'fuel' + with: + toolchain: latest + - name: rust cache uses: Swatinem/rust-cache@v2 with: @@ -276,6 +282,13 @@ jobs: env: RUST_BACKTRACE: 'full' + - name: agent tests (Fuel) + run: cargo test --release --package run-locally --bin run-locally --features fuel test-utils -- fuel::test --nocapture + if: matrix.e2e-type == 'fuel' + working-directory: ./rust/main + env: + RUST_BACKTRACE: 'full' + - name: Check for Rust file changes id: check-rust-changes run: | diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index e5429bdda1..32240fe5b8 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -254,7 +254,7 @@ checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" dependencies = [ "num-bigint 0.4.6", "num-traits", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -290,7 +290,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -346,7 +346,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", "synstructure 0.12.6", @@ -358,7 +358,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -419,9 +419,9 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -430,9 +430,9 @@ version = "0.1.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -488,7 +488,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7862e21c893d65a1650125d157eaeec691439379a1cee17ee49031b79236ada4" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -499,9 +499,9 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c87f3f15e7794432337fc718554eaa4dc8f04c9677a950ffe366f20a162ae42" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -638,7 +638,7 @@ checksum = "33b8de67cc41132507eeece2584804efcb15f85ba516e34c944b7667f480397a" dependencies = [ "heck 0.3.3", "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -771,12 +771,12 @@ dependencies = [ "lazycell", "peeking_take_while", "prettyplease", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "regex", "rustc-hash", "shlex", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -935,7 +935,7 @@ dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "syn 1.0.109", ] @@ -947,9 +947,9 @@ checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" dependencies = [ "once_cell", "proc-macro-crate 3.2.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "syn_derive", ] @@ -959,7 +959,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -970,7 +970,7 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -1057,7 +1057,7 @@ version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -1077,9 +1077,9 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc8b54b395f2fcfbb3d90c47b01c7f444d94d05bdeb775811dec868ac3bbc26" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -1257,7 +1257,7 @@ checksum = "ae6371b8bdc8b7d3959e9cf7b22d4435ef3e79e138688421ec654acf8c81b008" dependencies = [ "heck 0.4.1", "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -1700,9 +1700,9 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "029910b409398fdf81955d7301b906caf81f2c42b013ea074fbd89720229c424" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -1737,7 +1737,7 @@ version = "1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9acd45c63d41bc9b16bc6dc7f6bd604a8c2ad29ce96c8f3c96d7fc8ef384392e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -1748,9 +1748,9 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "edd3d80310cd7b86b09dbe886f4f2ca235a5ddb8d478493c6e50e720a3b38a42" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2009,9 +2009,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2135,7 +2135,7 @@ dependencies = [ "darling 0.13.4", "graphql-parser", "once_cell", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "strsim 0.10.0", "syn 1.0.109", @@ -2151,10 +2151,10 @@ dependencies = [ "darling 0.20.10", "once_cell", "ouroboros 0.18.4", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "strsim 0.10.0", - "syn 2.0.77", + "syn 2.0.98", "thiserror", ] @@ -2188,7 +2188,7 @@ dependencies = [ "cynic-codegen 3.9.0", "darling 0.20.10", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2229,7 +2229,7 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "strsim 0.10.0", "syn 1.0.109", @@ -2243,7 +2243,7 @@ checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "strsim 0.10.0", "syn 1.0.109", @@ -2257,10 +2257,10 @@ checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "strsim 0.11.1", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2293,7 +2293,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core 0.20.10", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2367,7 +2367,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -2378,7 +2378,7 @@ version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -2399,7 +2399,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" dependencies = [ "darling 0.14.4", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -2421,10 +2421,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case 0.4.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustc_version", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2442,9 +2442,9 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "unicode-xid 0.2.5", ] @@ -2559,9 +2559,9 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2861,7 +2861,7 @@ version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8958699f9359f0b04e691a13850d48b7de329138023876d07cbd024c2c820598" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -2872,9 +2872,9 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ab991c1362ac86c61ab6f556cff143daa22e5a15e4e189df818b2fd19fe65b" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -2884,9 +2884,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" dependencies = [ "once_cell", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -3089,7 +3089,7 @@ dependencies = [ "eyre", "getrandom 0.2.15", "hex 0.4.3", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "regex", "reqwest", @@ -3109,7 +3109,7 @@ dependencies = [ "ethers-contract-abigen", "ethers-core", "hex 0.4.3", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "serde_json", "syn 1.0.109", @@ -3132,7 +3132,7 @@ dependencies = [ "k256 0.11.6", "once_cell", "open-fastrlp", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "rand 0.8.5", "rlp 0.5.2", "rlp-derive", @@ -3470,12 +3470,12 @@ checksum = "bce44ac13b1971be7cea024a2003cf944522093dafec454fea9ff792f0ff2577" dependencies = [ "itertools 0.10.5", "lazy_static", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "regex", "serde", "serde_json", - "syn 2.0.77", + "syn 2.0.98", "thiserror", ] @@ -3655,9 +3655,9 @@ version = "0.58.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab0bc46a3552964bae5169e79b383761a54bd115ea66951a1a7a229edcefa55a" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "synstructure 0.13.1", ] @@ -3801,11 +3801,11 @@ dependencies = [ "Inflector", "fuel-abi-types", "itertools 0.12.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "regex", "serde_json", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -3845,9 +3845,9 @@ checksum = "5da75294c5e9da312bdc49239736699ee84ea9c5bfbc19a61a8ee588a1247aa1" dependencies = [ "fuels-code-gen", "itertools 0.12.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -3974,9 +3974,9 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -5139,7 +5139,7 @@ dependencies = [ "autocfg", "impl-tools-lib", "proc-macro-error", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -5149,9 +5149,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85d3946d886eaab0702fa0c6585adcced581513223fa9df7ccfabbd9fa331a88" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -5160,7 +5160,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -5255,7 +5255,7 @@ checksum = "6cfe3fc8519277af8e09e51b8987435e401d345d4466402e6a5b991143fdfa53" dependencies = [ "cosmwasm-std 2.1.3", "itertools 0.10.5", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -5581,10 +5581,10 @@ dependencies = [ "beef", "fnv", "lazy_static", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "regex-syntax 0.8.4", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -5793,7 +5793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22ce75669015c4f47b289fd4d4f56e894e4c96003ffdf3ac51313126f94c6cbb" dependencies = [ "cfg-if", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -5988,7 +5988,7 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -5999,9 +5999,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6101,7 +6101,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbff9bc912032c62bf65ef1d5aea88983b420f4f839db1e9b0c281a25c9c799" dependencies = [ "proc-macro-crate 1.2.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -6113,9 +6113,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96667db765a921f7b295ffee8b60472b686a51d4f21c2ee4ffdb94c7013b65a6" dependencies = [ "proc-macro-crate 1.2.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6125,9 +6125,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate 3.2.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6201,7 +6201,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "003b2be5c6c53c1cfeb0a238b8a1c3915cd410feb684457a36c10038f764bb1c" dependencies = [ "bytes", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -6227,9 +6227,9 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6295,7 +6295,7 @@ checksum = "5f7d21ccd03305a674437ee1248f3ab5d4b1db095cf1caf49f1713ddf61956b7" dependencies = [ "Inflector", "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -6308,10 +6308,10 @@ checksum = "39b0deead1528fd0e5947a8546a9642a9777c25f6e1e26f34c97b204bbb465bd" dependencies = [ "heck 0.4.1", "itertools 0.12.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "proc-macro2-diagnostics", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6359,7 +6359,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" dependencies = [ "proc-macro-crate 3.2.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -6489,7 +6489,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426" dependencies = [ "peg-runtime", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", ] @@ -6552,9 +6552,9 @@ checksum = "3c93a82e8d145725dcbaf44e5ea887c8a869efdcc28706df2d08c69e17077183" dependencies = [ "pest", "pest_meta", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6593,9 +6593,9 @@ version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6732,8 +6732,8 @@ version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" dependencies = [ - "proc-macro2 1.0.86", - "syn 2.0.77", + "proc-macro2 1.0.93", + "syn 2.0.98", ] [[package]] @@ -6794,7 +6794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", "version_check", @@ -6806,7 +6806,7 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "version_check", ] @@ -6822,9 +6822,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] @@ -6835,9 +6835,9 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "version_check", "yansi", ] @@ -6875,9 +6875,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6908,9 +6908,9 @@ checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" dependencies = [ "anyhow", "itertools 0.12.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6921,9 +6921,9 @@ checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3" dependencies = [ "anyhow", "itertools 0.12.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -6993,7 +6993,7 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -7085,7 +7085,7 @@ version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", ] [[package]] @@ -7284,9 +7284,9 @@ version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc303e793d3734489387d205e9b186fac9c6cfacedd98cbb2e8a5943595f3e6" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -7520,7 +7520,7 @@ version = "0.7.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -7549,7 +7549,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e33d7b2abe0c340d8797fe2907d3f20d3b5ea5908683618bfe80df7f621f672a" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -7598,6 +7598,8 @@ dependencies = [ "ethers-contract", "ethers-core", "eyre", + "fuels", + "futures", "hex 0.4.3", "hyperlane-base", "hyperlane-core", @@ -7609,6 +7611,7 @@ dependencies = [ "maplit", "nix 0.26.4", "once_cell", + "rand 0.8.5", "regex", "relayer", "ripemd", @@ -7975,7 +7978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62" dependencies = [ "proc-macro-crate 3.2.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -8006,7 +8009,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e953db32579999ca98c451d80801b6f6a7ecba6127196c5387ec0774c528befa" dependencies = [ "Inflector", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "schemafy_core", "serde", @@ -8033,10 +8036,10 @@ version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b1eee588578aff73f856ab961cd2f79e36bc45d7ded33a7562adba4667aecc0e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "serde_derive_internals", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -8159,7 +8162,7 @@ checksum = "28936f26d62234ff0be16f80115dbdeb3237fe9c25cf18fbcd1e3b3592360f20" dependencies = [ "bae", "heck 0.3.3", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -8219,7 +8222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "63f62030c60f3a691f5fe251713b4e220b306e50a71e1d6f9cce1f24bb781978" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", "thiserror", @@ -8243,7 +8246,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56821b7076f5096b8f726e2791ad255a99c82498e08ec477a65a96c461ff1927" dependencies = [ "heck 0.3.3", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", ] @@ -8264,7 +8267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69b4397b825df6ccf1e98bcdabef3bbcfc47ff5853983467850eeab878384f21" dependencies = [ "heck 0.3.3", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustversion", "syn 1.0.109", @@ -8444,9 +8447,9 @@ version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -8455,9 +8458,9 @@ version = "0.29.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -8488,9 +8491,9 @@ version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -8539,9 +8542,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a8fee4991ef4f274617a51ad4af30519438dacb2f56ac773b08a1922ff743350" dependencies = [ "darling 0.20.10", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -8961,7 +8964,7 @@ name = "solana-frozen-abi-macro" version = "1.14.13" source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustc_version", "syn 1.0.109", @@ -9203,7 +9206,7 @@ version = "1.14.13" source = "git+https://github.com/hyperlane-xyz/solana.git?tag=hyperlane-1.14.13-2024-11-20#913db71a07f967f4c5c7e7f747cb48517cdbf09e" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustversion", "syn 1.0.109", @@ -9545,7 +9548,7 @@ dependencies = [ "either", "heck 0.4.1", "once_cell", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "serde_json", "sqlx-core", @@ -9644,7 +9647,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustversion", "syn 1.0.109", @@ -9657,10 +9660,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0" dependencies = [ "heck 0.4.1", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustversion", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -9670,10 +9673,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ "heck 0.5.0", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "rustversion", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -9714,18 +9717,18 @@ version = "1.0.109" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.77" +version = "2.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "unicode-ident", ] @@ -9737,9 +9740,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" dependencies = [ "proc-macro-error", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -9760,7 +9763,7 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", "syn 1.0.109", "unicode-xid 0.2.5", @@ -9772,9 +9775,9 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -9981,9 +9984,9 @@ version = "1.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -10122,9 +10125,9 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -10426,9 +10429,9 @@ version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -10521,7 +10524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -10602,9 +10605,9 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70b20a22c42c8f1cd23ce5e34f165d4d37038f5b663ad20fb6adbdf029172483" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -10953,9 +10956,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "wasm-bindgen-shared", ] @@ -10987,9 +10990,9 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11452,9 +11455,9 @@ version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] @@ -11472,9 +11475,9 @@ version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ - "proc-macro2 1.0.86", + "proc-macro2 1.0.93", "quote 1.0.37", - "syn 2.0.77", + "syn 2.0.98", ] [[package]] diff --git a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs index 40bb99e10b..ddacf23754 100644 --- a/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs +++ b/rust/main/agents/scraper/migration/src/m20230309_000001_create_table_domain.rs @@ -359,6 +359,22 @@ const DOMAINS: &[RawDomain] = &[ is_test_net: true, is_deprecated: false, }, + RawDomain { + name: "fueltestnet", + token: "ETH", + domain: 1717982312, + chain_id: 1717982312, + is_test_net: true, + is_deprecated: false, + }, + RawDomain { + name: "fuelignition", + token: "ETH", + domain: 1717982311, + chain_id: 1717982311, + is_test_net: false, + is_deprecated: false, + }, RawDomain { name: "solanamainnet", token: "SOL", @@ -482,19 +498,19 @@ const DOMAINS: &[RawDomain] = &[ is_deprecated: false, }, RawDomain { - name: "fueltestnet", + name: "fueltest1", token: "ETH", - domain: 1717982312, - chain_id: 1717982312, + domain: 13373, + chain_id: 13373, is_test_net: true, is_deprecated: false, }, RawDomain { - name: "fuelignition", + name: "fueltest2", token: "ETH", - domain: 1717982311, - chain_id: 1717982311, - is_test_net: false, + domain: 13374, + chain_id: 13374, + is_test_net: true, is_deprecated: false, }, RawDomain { diff --git a/rust/main/hyperlane-core/src/chain.rs b/rust/main/hyperlane-core/src/chain.rs index 30dc48c4d6..8acfe6ea83 100644 --- a/rust/main/hyperlane-core/src/chain.rs +++ b/rust/main/hyperlane-core/src/chain.rs @@ -189,7 +189,8 @@ pub enum KnownHyperlaneDomain { Test1 = 9913371, Test2 = 9913372, Test3 = 9913373, - FuelTest1 = 13374, + FuelTest1 = 13373, + FuelTest2 = 13374, SealevelTest1 = 13375, SealevelTest2 = 13376, CosmosTest99990 = 99990, @@ -335,7 +336,7 @@ impl KnownHyperlaneDomain { PlumeTestnet, ScrollSepolia, Sepolia, SuperpositionTestnet, Abstracttestnet, Treasuretopaz ], LocalTestChain: [ - Test1, Test2, Test3, FuelTest1, SealevelTest1, SealevelTest2, CosmosTest99990, + Test1, Test2, Test3, FuelTest1, FuelTest2, SealevelTest1, SealevelTest2, CosmosTest99990, CosmosTest99991 ], }) @@ -361,7 +362,7 @@ impl KnownHyperlaneDomain { ScrollSepolia, Sepolia, SuperpositionTestnet ], - HyperlaneDomainProtocol::Fuel: [FuelTest1, FuelTestnet, FuelIgnition], + HyperlaneDomainProtocol::Fuel: [FuelTest1, FuelTest2, FuelTestnet, FuelIgnition], HyperlaneDomainProtocol::Sealevel: [EclipseMainnet, SolanaMainnet, SealevelTest1, SealevelTest2], HyperlaneDomainProtocol::Cosmos: [ Injective, Neutron, Osmosis, @@ -401,7 +402,7 @@ impl KnownHyperlaneDomain { Sei, SolanaMainnet, Taiko, Viction, Zetachain, FuelIgnition, // Local chains - CosmosTest99990, CosmosTest99991, FuelTest1, SealevelTest1, SealevelTest2, Test1, + CosmosTest99990, CosmosTest99991, FuelTest1, FuelTest2, SealevelTest1, SealevelTest2, Test1, Test2, Test3, // Test chains diff --git a/rust/main/utils/run-locally/Cargo.toml b/rust/main/utils/run-locally/Cargo.toml index 9dedae9cea..fd24adb9b4 100644 --- a/rust/main/utils/run-locally/Cargo.toml +++ b/rust/main/utils/run-locally/Cargo.toml @@ -36,6 +36,9 @@ regex.workspace = true relayer = { path = "../../agents/relayer" } hyperlane-cosmwasm-interface.workspace = true cosmwasm-schema.workspace = true +fuels.workspace = true +futures.workspace = true +rand.workspace = true [build-dependencies] anyhow = { workspace = true } @@ -43,3 +46,4 @@ vergen = { version = "8.3.2", features = ["build", "git", "gitcl"] } [features] cosmos = [] +fuel = [] diff --git a/rust/main/utils/run-locally/src/cosmos/mod.rs b/rust/main/utils/run-locally/src/cosmos/mod.rs index d786853338..9bf7417dcd 100644 --- a/rust/main/utils/run-locally/src/cosmos/mod.rs +++ b/rust/main/utils/run-locally/src/cosmos/mod.rs @@ -10,7 +10,6 @@ use cosmwasm_schema::cw_serde; use hyperlane_cosmos::RawCosmosAmount; use hyperlane_cosmwasm_interface::types::bech32_decode; use macro_rules_attribute::apply; -use maplit::hashmap; use tempfile::tempdir; mod cli; @@ -23,16 +22,19 @@ mod types; mod utils; use rpc::*; -use types::*; +pub use types::*; use utils::*; use crate::cosmos::link::link_networks; +use crate::invariants::base_termination_invariants_met; use crate::logging::log; use crate::metrics::agent_balance_sum; use crate::program::Program; +use crate::types::{AgentConfig, AgentConfigOut, HyperlaneStack}; use crate::utils::{as_task, concat_path, stop_child, AgentHandles, TaskHandle}; -use crate::{fetch_metric, AGENT_BIN_PATH}; -use cli::{OsmosisCLI, OsmosisEndpoint}; +use crate::AGENT_BIN_PATH; +pub use cli::OsmosisCLI; +use cli::OsmosisEndpoint; use self::deploy::deploy_cw_hyperlane; use self::source::{CLISource, CodeSource}; @@ -202,23 +204,6 @@ impl From<(CosmosResp, Deployments, String, u32, u32)> for CosmosNetwork { } } } -pub struct CosmosHyperlaneStack { - pub validators: Vec, - pub relayer: AgentHandles, - pub scraper: AgentHandles, - pub postgres: AgentHandles, -} - -impl Drop for CosmosHyperlaneStack { - fn drop(&mut self) { - for v in &mut self.validators { - stop_child(&mut v.1); - } - stop_child(&mut self.relayer.1); - stop_child(&mut self.scraper.1); - stop_child(&mut self.postgres.1); - } -} #[apply(as_task)] fn launch_cosmos_node(config: CosmosConfig) -> CosmosResp { @@ -478,7 +463,7 @@ fn run_locally() { .map(|v| { ( format!("cosmostest{}", v.domain), - AgentConfig::new(osmosisd.clone(), validator, v), + AgentConfig::cosmos(osmosisd.clone(), validator, v), ) }) .collect::>(), @@ -534,7 +519,7 @@ fn run_locally() { // dispatch the second batch of messages (after agents start) dispatched_messages += dispatch(&osmosisd, linker, &nodes); - let _stack = CosmosHyperlaneStack { + let _stack = HyperlaneStack { validators: hpl_val.into_iter().map(|v| v.join()).collect(), relayer: hpl_rly.join(), scraper: hpl_scr.join(), @@ -547,7 +532,7 @@ fn run_locally() { let mut failure_occurred = false; loop { // look for the end condition. - if termination_invariants_met( + if base_termination_invariants_met( hpl_rly_metrics_port, hpl_scr_metrics_port, dispatched_messages, @@ -625,113 +610,6 @@ fn dispatch(osmosisd: &Path, linker: &str, nodes: &[CosmosNetwork]) -> u32 { dispatched_messages } -fn termination_invariants_met( - relayer_metrics_port: u32, - scraper_metrics_port: u32, - messages_expected: u32, - starting_relayer_balance: f64, -) -> eyre::Result { - let expected_gas_payments = messages_expected; - let gas_payments_event_count = fetch_metric( - &relayer_metrics_port.to_string(), - "hyperlane_contract_sync_stored_events", - &hashmap! {"data_type" => "gas_payment"}, - )? - .iter() - .sum::(); - if gas_payments_event_count != expected_gas_payments { - log!( - "Relayer has indexed {} gas payments, expected {}", - gas_payments_event_count, - expected_gas_payments - ); - return Ok(false); - } - - let msg_processed_count = fetch_metric( - &relayer_metrics_port.to_string(), - "hyperlane_operations_processed_count", - &hashmap! {"phase" => "confirmed"}, - )? - .iter() - .sum::(); - if msg_processed_count != messages_expected { - log!( - "Relayer confirmed {} submitted messages, expected {}", - msg_processed_count, - messages_expected - ); - return Ok(false); - } - - let ending_relayer_balance: f64 = agent_balance_sum(relayer_metrics_port).unwrap(); - - // Make sure the balance was correctly updated in the metrics. - // Ideally, make sure that the difference is >= gas_per_tx * gas_cost, set here: - // https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/c2288eb31734ba1f2f997e2c6ecb30176427bc2c/rust/utils/run-locally/src/cosmos/cli.rs#L55 - // What's stopping this is that the format returned by the `uosmo` balance query is a surprisingly low number (0.000003999999995184) - // but then maybe the gas_per_tx is just very low - how can we check that? (maybe by simulating said tx) - if starting_relayer_balance <= ending_relayer_balance { - log!( - "Expected starting relayer balance to be greater than ending relayer balance, but got {} <= {}", - starting_relayer_balance, - ending_relayer_balance - ); - return Ok(false); - } - - let dispatched_messages_scraped = fetch_metric( - &scraper_metrics_port.to_string(), - "hyperlane_contract_sync_stored_events", - &hashmap! {"data_type" => "message_dispatch"}, - )? - .iter() - .sum::(); - if dispatched_messages_scraped != messages_expected { - log!( - "Scraper has scraped {} dispatched messages, expected {}", - dispatched_messages_scraped, - messages_expected - ); - return Ok(false); - } - - let gas_payments_scraped = fetch_metric( - &scraper_metrics_port.to_string(), - "hyperlane_contract_sync_stored_events", - &hashmap! {"data_type" => "gas_payment"}, - )? - .iter() - .sum::(); - if gas_payments_scraped != expected_gas_payments { - log!( - "Scraper has scraped {} gas payments, expected {}", - gas_payments_scraped, - expected_gas_payments - ); - return Ok(false); - } - - let delivered_messages_scraped = fetch_metric( - &scraper_metrics_port.to_string(), - "hyperlane_contract_sync_stored_events", - &hashmap! {"data_type" => "message_delivery"}, - )? - .iter() - .sum::(); - if delivered_messages_scraped != messages_expected { - log!( - "Scraper has scraped {} delivered messages, expected {}", - delivered_messages_scraped, - messages_expected - ); - return Ok(false); - } - - log!("Termination invariants have been meet"); - Ok(true) -} - #[cfg(feature = "cosmos")] mod test { diff --git a/rust/main/utils/run-locally/src/cosmos/types.rs b/rust/main/utils/run-locally/src/cosmos/types.rs index 18abd6cb8e..5235e8769e 100644 --- a/rust/main/utils/run-locally/src/cosmos/types.rs +++ b/rust/main/utils/run-locally/src/cosmos/types.rs @@ -1,12 +1,5 @@ -use std::{collections::BTreeMap, path::PathBuf}; - -use hyperlane_cosmwasm_interface::types::bech32_decode; - -use hyperlane_core::NativeToken; use hyperlane_cosmos::RawCosmosAmount; -use super::{cli::OsmosisCLI, CosmosNetwork}; - #[derive(serde::Serialize, serde::Deserialize)] pub struct TxEventAttr { pub key: String, @@ -88,103 +81,3 @@ pub struct AgentConfigAddrs { pub interchain_gas_paymaster: String, pub validator_announce: String, } - -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -pub struct AgentConfigSigner { - #[serde(rename = "type")] - pub typ: String, - pub key: String, - pub prefix: String, -} - -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -pub struct AgentConfigIndex { - pub from: u32, - pub chunk: u32, -} - -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -pub struct AgentUrl { - pub http: String, -} - -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -#[serde(rename_all = "camelCase")] -pub struct AgentConfig { - pub name: String, - pub domain_id: u32, - pub metrics_port: u32, - pub mailbox: String, - pub interchain_gas_paymaster: String, - pub validator_announce: String, - pub merkle_tree_hook: String, - pub protocol: String, - pub chain_id: String, - pub rpc_urls: Vec, - pub grpc_urls: Vec, - pub bech32_prefix: String, - pub signer: AgentConfigSigner, - pub index: AgentConfigIndex, - pub gas_price: RawCosmosAmount, - pub contract_address_bytes: usize, - pub native_token: NativeToken, -} - -#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] -pub struct AgentConfigOut { - pub chains: BTreeMap, -} - -fn to_hex_addr(addr: &str) -> String { - format!("0x{}", hex::encode(bech32_decode(addr).unwrap())) -} - -impl AgentConfig { - pub fn new(bin: PathBuf, validator: &str, network: &CosmosNetwork) -> Self { - let cli = OsmosisCLI::new(bin, network.launch_resp.home_path.to_str().unwrap()); - let validator = cli.get_keypair(validator); - - AgentConfig { - name: format!("cosmostest{}", network.domain), - domain_id: network.domain, - metrics_port: network.metrics_port, - mailbox: to_hex_addr(&network.deployments.mailbox), - interchain_gas_paymaster: to_hex_addr(&network.deployments.igp), - validator_announce: to_hex_addr(&network.deployments.va), - merkle_tree_hook: to_hex_addr(&network.deployments.hook_merkle), - protocol: "cosmos".to_string(), - chain_id: format!("cosmos-test-{}", network.domain), - rpc_urls: vec![AgentUrl { - http: format!( - "http://{}", - network.launch_resp.endpoint.rpc_addr.replace("tcp://", "") - ), - }], - grpc_urls: vec![ - // The first url points to a nonexistent node, but is used for checking fallback provider logic - AgentUrl { - http: "localhost:1337".to_string(), - }, - AgentUrl { - http: format!("http://{}", network.launch_resp.endpoint.grpc_addr), - }, - ], - bech32_prefix: "osmo".to_string(), - signer: AgentConfigSigner { - typ: "cosmosKey".to_string(), - key: format!("0x{}", hex::encode(validator.priv_key.to_bytes())), - prefix: "osmo".to_string(), - }, - gas_price: RawCosmosAmount { - denom: "uosmo".to_string(), - amount: "0.05".to_string(), - }, - contract_address_bytes: 32, - index: AgentConfigIndex { from: 1, chunk: 5 }, - native_token: NativeToken { - decimals: 6, - denom: "uosmo".to_string(), - }, - } - } -} diff --git a/rust/main/utils/run-locally/src/fuel/abis.rs b/rust/main/utils/run-locally/src/fuel/abis.rs new file mode 100644 index 0000000000..cd9ec7485c --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/abis.rs @@ -0,0 +1,48 @@ +use fuels::macros::abigen; + +abigen!( + Contract( + name = "AggregationISM", + abi = "utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-abi.json", + ), + Contract( + name = "DomainRoutingISM", + abi = "utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-abi.json", + ), + Contract( + name = "FallbackDomainRoutingHook", + abi = "utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-abi.json", + ), + Contract( + name = "GasOracle", + abi = "utils/run-locally/src/fuel/fuel-contracts/gas-oracle-abi.json", + ), + Contract( + name = "GasPaymaster", + abi = "utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-abi.json", + ), + Contract( + name = "PausableISM", + abi = "utils/run-locally/src/fuel/fuel-contracts/pausable-ism-abi.json", + ), + Contract( + name = "Mailbox", + abi = "utils/run-locally/src/fuel/fuel-contracts/mailbox-abi.json", + ), + Contract( + name = "MessageIdMultisigISM", + abi = "utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-abi.json", + ), + Contract( + name = "MerkleTreeHook", + abi = "utils/run-locally/src/fuel/fuel-contracts/merkle-tree-hook-abi.json", + ), + Contract( + name = "MsgRecipientTest", + abi = "utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-abi.json", + ), + Contract( + name = "ValidatorAnnounce", + abi = "utils/run-locally/src/fuel/fuel-contracts/validator-announce-abi.json", + ), +); diff --git a/rust/main/utils/run-locally/src/fuel/deploy.rs b/rust/main/utils/run-locally/src/fuel/deploy.rs new file mode 100644 index 0000000000..8c5337f340 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/deploy.rs @@ -0,0 +1,290 @@ +use ethers::types::H160; +use fuels::{ + accounts::wallet::WalletUnlocked, + programs::contract::{Contract, LoadConfiguration}, + types::{transaction::TxPolicies, Bits256, ContractId, EvmAddress, Identity, Salt}, +}; +use rand::{thread_rng, Rng}; + +use crate::{fuel::abis::*, log}; + +pub struct FuelDeployments { + pub gas_paymaster: GasPaymaster, + pub mailbox: Mailbox, + pub merkle_tree_hook: MerkleTreeHook, + pub msg_recipient_test: MsgRecipientTest, + pub validator_announce: ValidatorAnnounce, +} + +/// Ensures random deployment addresses each run +fn get_deployment_config() -> LoadConfiguration { + let mut bytes = [0u8; 32]; + thread_rng().fill(&mut bytes[..]); + let salt = Salt::new(bytes); + + LoadConfiguration::default().with_salt(salt) +} + +pub async fn deploy_fuel_hyperlane( + wallet: WalletUnlocked, + origin_domain: u32, + target_domain: u32, + validator_addr: H160, +) -> FuelDeployments { + let aggregation_ism_id = Contract::load_from( + "./src/fuel/fuel-contracts/aggregation-ism.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let domain_routing_ism_id = Contract::load_from( + "./src/fuel/fuel-contracts/domain-routing-ism.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let fallback_domain_routing_hook_id = Contract::load_from( + "./src/fuel/fuel-contracts/fallback-domain-routing-hook.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let gas_oracle_id = Contract::load_from( + "./src/fuel/fuel-contracts/gas-oracle.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let igp_id = Contract::load_from( + "./src/fuel/fuel-contracts/gas-paymaster.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let configurables = MailboxConfigurables::default() + .with_LOCAL_DOMAIN(origin_domain) + .unwrap(); + let mailbox_id = Contract::load_from( + "./src/fuel/fuel-contracts/mailbox.bin", + get_deployment_config().with_configurables(configurables), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let configurables = MessageIdMultisigISMConfigurables::default() + .with_THRESHOLD(1) + .unwrap(); + let message_id_multisig_ism_id = Contract::load_from( + "./src/fuel/fuel-contracts/message-id-multisig-ism.bin", + get_deployment_config().with_configurables(configurables), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let pausable_ism_id = Contract::load_from( + "./src/fuel/fuel-contracts/pausable-ism.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let merkle_tree_hook_id = Contract::load_from( + "./src/fuel/fuel-contracts/merkle-tree-hook.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let msg_recipient_test_id = Contract::load_from( + "./src/fuel/fuel-contracts/msg-recipient-test.bin", + get_deployment_config(), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + let configurables = ValidatorAnnounceConfigurables::default() + .with_LOCAL_DOMAIN(origin_domain) + .unwrap() + .with_MAILBOX_ID(mailbox_id.clone().into()) + .unwrap(); + + let validator_announce_id = Contract::load_from( + "./src/fuel/fuel-contracts/validator-announce.bin", + get_deployment_config().with_configurables(configurables), + ) + .unwrap() + .deploy(&wallet, TxPolicies::default()) + .await + .unwrap(); + + log!("Fuel contracts deployed on {:?} ✅", origin_domain); + log!("Initializing contracts..."); + + let owner = Identity::from(wallet.address()); + let aggregation_ism = AggregationISM::new(aggregation_ism_id.clone(), wallet.clone()); + + let aggregate_isms: Vec = vec![ + message_id_multisig_ism_id.clone().into(), + pausable_ism_id.clone().into(), + ]; + aggregation_ism + .methods() + .initialize(owner, aggregate_isms, 2) + .call() + .await + .unwrap(); + + let domain_routing_ism = DomainRoutingISM::new(domain_routing_ism_id.clone(), wallet.clone()); + + domain_routing_ism + .methods() + .initialize_with_domains( + owner, + vec![target_domain], + vec![Bits256(ContractId::from(aggregation_ism_id.clone()).into())], + ) + .call() + .await + .unwrap(); + + let fallback_domain_routing_hook = + FallbackDomainRoutingHook::new(fallback_domain_routing_hook_id.clone(), wallet.clone()); + + fallback_domain_routing_hook + .methods() + .initialize_ownership(owner) + .call() + .await + .unwrap(); + fallback_domain_routing_hook + .methods() + .set_hook( + target_domain, + Bits256(ContractId::from(merkle_tree_hook_id.clone()).into()), + ) + .call() + .await + .unwrap(); + + let gas_oracle = GasOracle::new(gas_oracle_id.clone(), wallet.clone()); + + gas_oracle + .methods() + .initialize_ownership(owner) + .call() + .await + .unwrap(); + let gas_oracle_configs = vec![RemoteGasDataConfig { + domain: target_domain, + remote_gas_data: RemoteGasData { + domain: target_domain, + gas_price: 500, + token_exchange_rate: 1, // since sending Fuel to Fuel + token_decimals: 9, + }, + }]; + gas_oracle + .methods() + .set_remote_gas_data_configs(gas_oracle_configs) + .call() + .await + .unwrap(); + + let gas_paymaster = GasPaymaster::new(igp_id.clone(), wallet.clone()); + + gas_paymaster + .methods() + .initialize(owner, owner) + .call() + .await + .unwrap(); + gas_paymaster + .methods() + .set_gas_oracle( + target_domain, + Bits256(ContractId::from(gas_oracle_id.clone()).into()), + ) + .call() + .await + .unwrap(); + + let mailbox = Mailbox::new(mailbox_id.clone(), wallet.clone()); + + mailbox + .methods() + .initialize( + owner, + Bits256(ContractId::from(domain_routing_ism_id.clone()).into()), + Bits256(ContractId::from(fallback_domain_routing_hook_id.clone()).into()), + Bits256(ContractId::from(igp_id.clone()).into()), + ) + .call() + .await + .unwrap(); + + let message_id_multisig_ism = + MessageIdMultisigISM::new(message_id_multisig_ism_id, wallet.clone()); + + let validators = { + let mut padded = [0u8; 32]; + padded[12..].copy_from_slice(&validator_addr.0); + vec![EvmAddress::from(Bits256(padded))] + }; + message_id_multisig_ism + .methods() + .initialize(validators) + .call() + .await + .unwrap(); + + let pausable_ism = PausableISM::new(pausable_ism_id, wallet.clone()); + pausable_ism + .methods() + .initialize_ownership(owner) + .call() + .await + .unwrap(); + + let merkle_tree_hook = MerkleTreeHook::new(merkle_tree_hook_id, wallet.clone()); + merkle_tree_hook + .methods() + .initialize(mailbox_id) + .call() + .await + .unwrap(); + + log!("Fuel contracts initialized on {:?} ✅", origin_domain); + + FuelDeployments { + gas_paymaster, + mailbox, + merkle_tree_hook, + msg_recipient_test: MsgRecipientTest::new(msg_recipient_test_id, wallet.clone()), + validator_announce: ValidatorAnnounce::new(validator_announce_id, wallet.clone()), + } +} diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-abi.json new file mode 100644 index 0000000000..bacd826d03 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-abi.json @@ -0,0 +1,768 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "(struct std::vec::Vec, u8)", + "concreteTypeId": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::isms::aggregation_ism::AggregationIsmError", + "concreteTypeId": "d132a0a455da99b27af77b6df0f334147b4f0872c3f22da9d452ab0baba6e461", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 3 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 4 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 5 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 6 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 7 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 11 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 13 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "b8ca7626a08e8fb93379b5d9d58d8a12eede8de9f087bfa21feccca44f92e211", + "metadataTypeId": 15, + "typeArguments": [ + "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 17 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 18 + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 15, + "typeArguments": [ + { + "name": "", + "typeId": 13 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::aggregation_ism::AggregationIsmError", + "metadataTypeId": 2, + "components": [ + { + "name": "DidNotMeetThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 3, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 4, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 5, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 6 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 6, + "components": [ + { + "name": "Address", + "typeId": 10 + }, + { + "name": "ContractId", + "typeId": 13 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 7, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 8 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 9 + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 11, + "components": [ + { + "name": "buf", + "typeId": 12 + }, + { + "name": "len", + "typeId": 19 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 12, + "components": [ + { + "name": "ptr", + "typeId": 9 + }, + { + "name": "cap", + "typeId": 19 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 13, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 14, + "components": [ + { + "name": "ptr", + "typeId": 9 + }, + { + "name": "cap", + "typeId": 19 + } + ], + "typeParameters": [ + 8 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 15, + "components": [ + { + "name": "buf", + "typeId": 14, + "typeArguments": [ + { + "name": "", + "typeId": 8 + } + ] + }, + { + "name": "len", + "typeId": 19 + } + ], + "typeParameters": [ + 8 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 16, + "components": [ + { + "name": "previous_owner", + "typeId": 6 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 6 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 18, + "components": [ + { + "name": "new_owner", + "typeId": 6 + }, + { + "name": "previous_owner", + "typeId": 6 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 19 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ModuleType] - The type of security model." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Verifies the message using the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be verified." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If any external call fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the verifications do not meet the threshold." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "modules_and_threshold", + "output": "338f8824eff0cecf524266f2ab1e824b639f96afdeef1cbd5b1c66f9f50bb70e", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the modules and threshold for the Aggregation ISM for the given message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of modules to be used for message verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u8] - The threshold of approval for the Aggregation ISM." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "modules", + "concreteTypeId": "b8ca7626a08e8fb93379b5d9d58d8a12eede8de9f087bfa21feccca44f92e211" + }, + { + "name": "threshold", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Initializes the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `owner`: [Identity] - The address to be set as the owner of the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is already initialized." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "15074287530437941682", + "concreteTypeId": "d132a0a455da99b27af77b6df0f334147b4f0872c3f22da9d452ab0baba6e461" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-storage_slots.json new file mode 100644 index 0000000000..28e697068f --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism-storage_slots.json @@ -0,0 +1,6 @@ +[ + { + "key": "039bf66740422794083923f525e8759e120ad9321771c63f8bc14d4b8329fd36", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/aggregation-ism.bin new file mode 100644 index 0000000000000000000000000000000000000000..55e8308e4ea85a457ccd8b10ecf044470e71424b GIT binary patch literal 33776 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ξr{rcY>XtUs@FF}8+$ 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", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "metadataTypeId": 14, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "metadataTypeId": 14, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 15 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 17 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 18 + }, + { + "name": "__tuple_element", + "typeId": 18 + } + ] + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 1, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::routing::domain_routing_ism::DomainRoutingIsmError", + "metadataTypeId": 2, + "components": [ + { + "name": "DomainModuleLengthMismatch", + "typeId": 0 + }, + { + "name": "DomainNotSet", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 3, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 4, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 5 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 5, + "components": [ + { + "name": "Address", + "typeId": 9 + }, + { + "name": "ContractId", + "typeId": 12 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 6, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 7 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 8 + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 9, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 10, + "components": [ + { + "name": "buf", + "typeId": 11 + }, + { + "name": "len", + "typeId": 18 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 11, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 12, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 13, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 14, + "components": [ + { + "name": "buf", + "typeId": 13, + "typeArguments": [ + { + "name": "", + "typeId": 7 + } + ] + }, + { + "name": "len", + "typeId": 18 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 15, + "components": [ + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 16, + "components": [ + { + "name": "new_owner", + "typeId": 5 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 5 + }, + { + "name": "previous_owner", + "typeId": 5 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 18 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ModuleType] - The type of security model." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Verifies the message using the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be verified." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the ISM is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the ISM call fails." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "route", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the ISM responsible for verifying the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - Formatted Hyperlane message" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [b256] - The ISM to use to verify the message" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the domain is not set." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "domains", + "output": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the domains that have been set" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of origin domains." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "domains", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a" + }, + { + "name": "modules", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198" + } + ], + "name": "initialize_with_domains", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the ISMs to be used for the specified origin domains" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `owner`: [Identity] - The address of the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domains`: [Vec] - The list of origin domains." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `modules`: [Vec] - The list of ISMs to be used for the specified domains." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the ISM is already initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the length of the domains and modules do not match." + ] + }, + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "module", + "output": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the ISM to be used for the specified origin domain" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The origin domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [b256] - The ISM to be used for the specified domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the domain is not set." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "remove", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Removes the specified origin domain" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The origin domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the ISM is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "module", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the ISM to be used for the specified origin domain" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The origin domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `module`: [b256] - The ISM to be used for the specified domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the ISM is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "write", + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "6117547327087567475", + "concreteTypeId": "54e5e4e1bfb1e273ecadd2b7a727ee56d90c3df245f1c67629cf4b5a0be1d1d7" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-storage_slots.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism-storage_slots.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/domain-routing-ism.bin new file mode 100644 index 0000000000000000000000000000000000000000..ae3c2e61f46c71482c0bedfe5b2da95ddbf50dd2 GIT binary patch literal 39952 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 UK4N~?zTW=Yfvul0*Uk6*FEuXy>Hq)$ literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-abi.json new file mode 100644 index 0000000000..86ff2381c4 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-abi.json @@ -0,0 +1,880 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "concreteTypeId": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "metadataTypeId": 0 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 1 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 2 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 3 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 4 + }, + { + "type": "struct interfaces::hooks::fallback_domain_routing_hook::HookConfig", + "concreteTypeId": "e8a4be5c9756e97a11e6d958e2a34c40efdbb447a1839760219ad0199b05931c", + "metadataTypeId": 7 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 9 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "2ff1fbc38df253752accaa0908e3f5e405a92943b31768bcd12ae53f43011624", + "metadataTypeId": 13, + "typeArguments": [ + "e8a4be5c9756e97a11e6d958e2a34c40efdbb447a1839760219ad0199b05931c" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 14 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 15 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 16 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "metadataTypes": [ + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "metadataTypeId": 0, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_TREE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "INTERCHAIN_GAS_PAYMASTER", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FALLBACK_ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ID_AUTH_ISM", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PAUSABLE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PROTOCOL_FEE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LAYER_ZERO_V1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "RATE_LIMITED_HOOK", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 1, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 2, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 3 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 3, + "components": [ + { + "name": "Address", + "typeId": 8 + }, + { + "name": "ContractId", + "typeId": 11 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 4, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 5 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct interfaces::hooks::fallback_domain_routing_hook::HookConfig", + "metadataTypeId": 7, + "components": [ + { + "name": "destination", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "hook", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 8, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 9, + "components": [ + { + "name": "buf", + "typeId": 10 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 10, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 11, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 12, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 13, + "components": [ + { + "name": "buf", + "typeId": 12, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 14, + "components": [ + { + "name": "previous_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 15, + "components": [ + { + "name": "new_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 16, + "components": [ + { + "name": "new_owner", + "typeId": 3 + }, + { + "name": "previous_owner", + "typeId": 3 + } + ] + } + ], + "functions": [ + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "fallback", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Initializes the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `owner`: [Identity] - The owner of the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `fallback`: [b256] - The hook to fall back to if no hook is found." + ] + }, + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "destination", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "hook", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set_hook", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the hook for a given destinationd domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `destination`: [u32] - The destination domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `hook`: [b256] - The hook to call for that domain." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "hooks", + "concreteTypeId": "2ff1fbc38df253752accaa0908e3f5e405a92943b31768bcd12ae53f43011624" + } + ], + "name": "set_hooks", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the hooks for multiple destination domains." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `hooks`: [Vec] - The hooks to set." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "hook_type", + "output": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of hook" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [PostDispatchHookType] - The type of the hook." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "post_dispatch", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Post action after a message is dispatched via the Mailbox" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " For the MerkleTreeHook, this function inserts the message ID into the MerkleTree." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is paused." + ] + }, + { + "name": "payable", + "arguments": [] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "quote_dispatch", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Compute the payment required by the postDispatch call" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The payment required for the postDispatch call." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "_metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "supports_metadata", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns whether the hook supports metadata" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be checked." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - Whether the hook supports the metadata." + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-storage_slots.json new file mode 100644 index 0000000000..202999e75d --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook-storage_slots.json @@ -0,0 +1,6 @@ +[ + { + "key": "bb66001e854316e6b1143fee692fc9fec9f8412a3d512a78b961222e42fb6202", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/fallback-domain-routing-hook.bin new file mode 100644 index 0000000000000000000000000000000000000000..01658c72db3cafb7012b92818a0ebce42bbb1770 GIT binary patch literal 31352 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 literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-abi.json new file mode 100644 index 0000000000..aacc0bd906 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-abi.json @@ -0,0 +1,625 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 1 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 2 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 3 + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 4 + }, + { + "type": "struct interfaces::hooks::gas_oracle::ExchangeRateAndGasData", + "concreteTypeId": "9b806e0ead09025957d6856cb508ef188a7c7e19a39b99110f44f905bf919e12", + "metadataTypeId": 7 + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "concreteTypeId": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "metadataTypeId": 8 + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasDataConfig", + "concreteTypeId": "f639e556b00763e80146327e7a56fdcace4646dbcf835e822f810dee15062f36", + "metadataTypeId": 9 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "d837a2e1ca84a6b9b55fdd75d5470b44f16ac86bc0b45fc163ca38dbda7899e8", + "metadataTypeId": 14, + "typeArguments": [ + "f639e556b00763e80146327e7a56fdcace4646dbcf835e822f810dee15062f36" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 15 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 16 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 17 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypes": [ + { + "type": "b256", + "metadataTypeId": 0 + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 1, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 2, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 3 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 3, + "components": [ + { + "name": "Address", + "typeId": 10 + }, + { + "name": "ContractId", + "typeId": 11 + } + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 4, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 5 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct interfaces::hooks::gas_oracle::ExchangeRateAndGasData", + "metadataTypeId": 7, + "components": [ + { + "name": "token_exchange_rate", + "typeId": 12 + }, + { + "name": "gas_price", + "typeId": 12 + } + ] + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "metadataTypeId": 8, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "token_exchange_rate", + "typeId": 12 + }, + { + "name": "gas_price", + "typeId": 12 + }, + { + "name": "token_decimals", + "typeId": 19 + } + ] + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasDataConfig", + "metadataTypeId": 9, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "remote_gas_data", + "typeId": 8 + } + ] + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 10, + "components": [ + { + "name": "bits", + "typeId": 0 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 11, + "components": [ + { + "name": "bits", + "typeId": 0 + } + ] + }, + { + "type": "struct std::u128::U128", + "metadataTypeId": 12, + "components": [ + { + "name": "upper", + "typeId": 18 + }, + { + "name": "lower", + "typeId": 18 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 13, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": 18 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 14, + "components": [ + { + "name": "buf", + "typeId": 13, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": 18 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 15, + "components": [ + { + "name": "previous_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 16, + "components": [ + { + "name": "new_owner", + "typeId": 3 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 17, + "components": [ + { + "name": "new_owner", + "typeId": 3 + }, + { + "name": "previous_owner", + "typeId": 3 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 18 + }, + { + "type": "u8", + "metadataTypeId": 19 + } + ], + "functions": [ + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_exchange_rate_and_gas_price", + "output": "9b806e0ead09025957d6856cb508ef188a7c7e19a39b99110f44f905bf919e12", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the token exchange rate and gas price for a given domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas data for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ExchangeRateAndGasData] - The exchange rate and gas price for the remote domain." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_remote_gas_data", + "output": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the gas data from storage." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas data for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [RemoteGasData] - The gas data for the remote domain." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "configs", + "concreteTypeId": "d837a2e1ca84a6b9b55fdd75d5470b44f16ac86bc0b45fc163ca38dbda7899e8" + } + ], + "name": "set_remote_gas_data_configs", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the gas data for a given domain. Only callable by the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `configs`: [Vec]<[RemoteGasDataConfig]> - The remote gas data configs to set." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-storage_slots.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle-storage_slots.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-oracle.bin new file mode 100644 index 0000000000000000000000000000000000000000..87fd69a1d8a5e0e944a0e225d828d51fac445c0b GIT binary patch literal 23088 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 LvFB}l+t>d;tH0{O literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-abi.json new file mode 100644 index 0000000000..d427bbe4b5 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-abi.json @@ -0,0 +1,2063 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::hooks::igp::IgpError", + "concreteTypeId": "e8ec08fc35b6312eaeca1be8ba0645b2eb1bf5656f53fed618eda7c184a7c6bc", + "metadataTypeId": 0 + }, + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "concreteTypeId": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "metadataTypeId": 1 + }, + { + "type": "enum standards::src5::AccessError", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d", + "metadataTypeId": 2 + }, + { + "type": "enum standards::src5::State", + "concreteTypeId": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "metadataTypeId": 3 + }, + { + "type": "enum std::identity::Identity", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "metadataTypeId": 4 + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "metadataTypeId": 5, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "191bf2140761b3c5ab6c43992d162bb3dc9d7f2272b2ee5f5eeea411ddedcd32", + "metadataTypeId": 5, + "typeArguments": [ + "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974" + ] + }, + { + "type": "enum std::option::Option", + "concreteTypeId": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "metadataTypeId": 5, + "typeArguments": [ + "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893", + "metadataTypeId": 6 + }, + { + "type": "str", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "concreteTypeId": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "metadataTypeId": 9 + }, + { + "type": "struct interfaces::hooks::igp::BeneficiarySetEvent", + "concreteTypeId": "229f9e763c8424886a0b828eb92ecd7ee7ee60fb9b34ec5595a43cc02b21a6e7", + "metadataTypeId": 10 + }, + { + "type": "struct interfaces::hooks::igp::ClaimEvent", + "concreteTypeId": "f6197f499ee863b7f79af9d4149ec4c76ac1f12af5d55ac5a3e9aa2adf195bc9", + "metadataTypeId": 11 + }, + { + "type": "struct interfaces::hooks::igp::DestinationGasConfigSetEvent", + "concreteTypeId": "b8b47e85d8cb1e8bd7a47922d6ac2c9aef8c272feb8d5a404e972bb189aeedb3", + "metadataTypeId": 12 + }, + { + "type": "struct interfaces::hooks::igp::DomainGasConfig", + "concreteTypeId": "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b", + "metadataTypeId": 13 + }, + { + "type": "struct interfaces::hooks::igp::GasOracleSetEvent", + "concreteTypeId": "9a9d03fe63ecba2bda69c30f8c743b0d5719d4dc01ad2cbbedce34332ae57970", + "metadataTypeId": 14 + }, + { + "type": "struct interfaces::hooks::igp::GasPaymentEvent", + "concreteTypeId": "8dfafd11d278da7cc3347b4432a7bd4dbb4dbc21d2475f98b8ae17b0a1a5c122", + "metadataTypeId": 15 + }, + { + "type": "struct std::asset_id::AssetId", + "concreteTypeId": "c0710b6731b1dd59799cf6bef33eee3b3b04a2e40e80a0724090215bbf2ca974", + "metadataTypeId": 17 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 18 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "72e5e46f1e7d3f8964a9236d110d456cb86fea809e436c91f60e6503b65f9f1d", + "metadataTypeId": 23, + "typeArguments": [ + "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a", + "metadataTypeId": 23, + "typeArguments": [ + "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed", + "metadataTypeId": 24 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5", + "metadataTypeId": 25 + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308", + "metadataTypeId": 26 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u64", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "enum interfaces::hooks::igp::IgpError", + "metadataTypeId": 0, + "components": [ + { + "name": "InsufficientGasPayment", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InterchainGasPaymentInBaseAsset", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "UnsupportedMetadataFormat", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InvalidDomainConfigLength", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::hooks::post_dispatch_hook::PostDispatchHookType", + "metadataTypeId": 1, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_TREE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "INTERCHAIN_GAS_PAYMASTER", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FALLBACK_ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ID_AUTH_ISM", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PAUSABLE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "PROTOCOL_FEE", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LAYER_ZERO_V1", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "RATE_LIMITED_HOOK", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::AccessError", + "metadataTypeId": 2, + "components": [ + { + "name": "NotOwner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum standards::src5::State", + "metadataTypeId": 3, + "components": [ + { + "name": "Uninitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Initialized", + "typeId": 4 + }, + { + "name": "Revoked", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum std::identity::Identity", + "metadataTypeId": 4, + "components": [ + { + "name": "Address", + "typeId": 16 + }, + { + "name": "ContractId", + "typeId": 20 + } + ] + }, + { + "type": "enum std::option::Option", + "metadataTypeId": 5, + "components": [ + { + "name": "None", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "Some", + "typeId": 7 + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "enum sway_libs::ownership::errors::InitializationError", + "metadataTypeId": 6, + "components": [ + { + "name": "CannotReinitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 7 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 8 + }, + { + "type": "struct interfaces::hooks::gas_oracle::RemoteGasData", + "metadataTypeId": 9, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "token_exchange_rate", + "typeId": 21 + }, + { + "name": "gas_price", + "typeId": 21 + }, + { + "name": "token_decimals", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::BeneficiarySetEvent", + "metadataTypeId": 10, + "components": [ + { + "name": "beneficiary", + "typeId": 4 + } + ] + }, + { + "type": "struct interfaces::hooks::igp::ClaimEvent", + "metadataTypeId": 11, + "components": [ + { + "name": "beneficiary", + "typeId": 4 + }, + { + "name": "amount", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::DestinationGasConfigSetEvent", + "metadataTypeId": 12, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "overhead", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::DomainGasConfig", + "metadataTypeId": 13, + "components": [ + { + "name": "gas_oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "gas_overhead", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::GasOracleSetEvent", + "metadataTypeId": 14, + "components": [ + { + "name": "domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct interfaces::hooks::igp::GasPaymentEvent", + "metadataTypeId": 15, + "components": [ + { + "name": "message_id", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "destination_domain", + "typeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_amount", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "payment", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::address::Address", + "metadataTypeId": 16, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::asset_id::AssetId", + "metadataTypeId": 17, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 18, + "components": [ + { + "name": "buf", + "typeId": 19 + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 19, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 20, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::u128::U128", + "metadataTypeId": 21, + "components": [ + { + "name": "upper", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "lower", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 22, + "components": [ + { + "name": "ptr", + "typeId": 8 + }, + { + "name": "cap", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 23, + "components": [ + { + "name": "buf", + "typeId": 22, + "typeArguments": [ + { + "name": "", + "typeId": 7 + } + ] + }, + { + "name": "len", + "typeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "typeParameters": [ + 7 + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipRenounced", + "metadataTypeId": 24, + "components": [ + { + "name": "previous_owner", + "typeId": 4 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipSet", + "metadataTypeId": 25, + "components": [ + { + "name": "new_owner", + "typeId": 4 + } + ] + }, + { + "type": "struct sway_libs::ownership::events::OwnershipTransferred", + "metadataTypeId": 26, + "components": [ + { + "name": "new_owner", + "typeId": 4 + }, + { + "name": "previous_owner", + "typeId": 4 + } + ] + } + ], + "functions": [ + { + "inputs": [], + "name": "beneficiary", + "output": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the current beneficiary." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Identity] - The beneficiary." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "asset", + "concreteTypeId": "191bf2140761b3c5ab6c43992d162bb3dc9d7f2272b2ee5f5eeea411ddedcd32" + } + ], + "name": "claim", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sends all base asset funds to the beneficiary. Callable by anyone." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "gas_oracle", + "output": "0c2beb9013490c4f753f2757dfe2d8340b22ce3827d596d81d249b7038033cb6", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the gas oracle for a domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas oracle for." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "get_current_domain_gas", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the gas amount for the current domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The gas amount for the current domain." + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_domain_gas_config", + "output": "daf5a9441e8f4aed11368121fb8cd7fcaec71d243bf701ceefd0cd2aba270d8b", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the gas config for a domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas config for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [DomainGasConfig] - The gas config for the domain (gas overhead and oracle address)." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "get_remote_gas_data", + "output": "7b4c89ae67dd062b19fc7f4acf9b99d824182c6051d7c26c06be18c1de085595", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the exchange rate and gas price for a given domain using the" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " configured gas oracle." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas data for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [RemoteGasData] - Remote gas data for the domain from the oracle." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If no gas oracle is set." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + }, + { + "name": "beneficiary", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Initializes the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `owner`: [Identity] - The owner of the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `beneficiary`: [Identity] - The beneficiary of the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is already initialized." + ] + }, + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "message_id", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_amount", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + }, + { + "name": "refund_address", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "pay_for_gas", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Allows the caller to pay for gas." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message_id`: [b256] - The message ID." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `destination_domain`: [u32] - The domain to pay for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `gas_amount`: [u64] - The amount of gas." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `refund_address`: [Identity] - The address to refund the excess payment to." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If asset sent is not the base asset." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the payment is less than the required amount." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the metadata is invalid." + ] + }, + { + "name": "payable", + "arguments": [] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "destination_domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_amount", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "quote_gas_payment", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Quotes the required interchain gas payment to be paid in the base asset." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `destination_domain`: [u32] - The destination domain of the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `gas_amount`: [u64] - The amount of destination gas to pay for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The total payment for the gas amount." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "beneficiary", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "set_beneficiary", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the beneficiary to `beneficiary`. Only callable by the owner." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `beneficiary`: [Identity] - The new beneficiary." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "13c38f4111bad6468fad4f8ea82fd744546b63be49db9439fb3d94e14ae2bb3a" + }, + { + "name": "config", + "concreteTypeId": "72e5e46f1e7d3f8964a9236d110d456cb86fea809e436c91f60e6503b65f9f1d" + } + ], + "name": "set_destination_gas_config", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the gas configs for a destination domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [Vec] - The domains to set the gas config for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `config`: [Vec] - The gas config to set." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_oracle", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ], + "name": "set_gas_oracle", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the gas oracle for a domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to set the gas oracle for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `gas_oracle`: [b256] - The gas oracle." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "initialize_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "only_owner", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "owner", + "output": "192bc7098e2fe60635a9918afb563e4e5419d386da2bdbf0d716b4bc8549802c", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "renounce_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "new_owner", + "concreteTypeId": "ab7cd04e05be58e3fc15d424c2c4a57f824a2a2d97d67252440a3925ebdc1335" + } + ], + "name": "transfer_ownership", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "gas_overhead", + "output": "d852149004cc9ec0bbe7dc4e37bffea1d41469b759512b6136f2e865a4c06e7d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Gets the gas overhead for a given domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to get the gas overhead for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The gas overhead." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "domain", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "gas_overhead", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0" + } + ], + "name": "set_gas_overhead", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Sets the gas overhead for a given domain." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `domain`: [u32] - The domain to set the gas overhead for." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `gas_overhead`: [u64] - The gas overhead." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the caller is not the owner." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "hook_type", + "output": "88d5bf06eca6ec129b0c98e6d67271d9012ccd96caf9fe498d5dd2d191db9428", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of hook" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [PostDispatchHookType] - The type of the hook." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "post_dispatch", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Manages payments on a source chain to cover gas costs of relaying" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " messages to destination chains and includes the gas overhead per destination" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " The intended use of this contract is to store overhead gas amounts for destination" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " domains, e.g. Mailbox and ISM gas usage, such that users of this IGP are only required" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " to specify the gas amount used by their own applications." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message being dispatched." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message is invalid" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If IGP call fails" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If metadata is invalid" + ] + }, + { + "name": "payable", + "arguments": [] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "quote_dispatch", + "output": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Compute the payment required by the postDispatch call" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata required for the hook." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message being dispatched." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u64] - The payment required for the postDispatch call." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is not initialized." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the message is invalid" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If IGP call fails" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If metadata is invalid" + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "supports_metadata", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns whether the hook supports metadata" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be checked." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - Whether the hook supports the metadata." + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "17733344961923408823", + "concreteTypeId": "f6197f499ee863b7f79af9d4149ec4c76ac1f12af5d55ac5a3e9aa2adf195bc9" + }, + { + "logId": "2161305517876418151", + "concreteTypeId": "1dfe7feadc1d9667a4351761230f948744068a090fe91b1bc6763a90ed5d3893" + }, + { + "logId": "16280289466020123285", + "concreteTypeId": "e1ef35033ea9d2956f17c3292dea4a46ce7d61fdf37bbebe03b7b965073f43b5" + }, + { + "logId": "16783799790628909358", + "concreteTypeId": "e8ec08fc35b6312eaeca1be8ba0645b2eb1bf5656f53fed618eda7c184a7c6bc" + }, + { + "logId": "10098701174489624218", + "concreteTypeId": "8c25cb3686462e9a86d2883c5688a22fe738b0bbc85f458d2d2b5f3f667c6d5a" + }, + { + "logId": "10230767756512909948", + "concreteTypeId": "8dfafd11d278da7cc3347b4432a7bd4dbb4dbc21d2475f98b8ae17b0a1a5c122" + }, + { + "logId": "4571204900286667806", + "concreteTypeId": "3f702ea3351c9c1ece2b84048006c8034a24cbc2bad2e740d0412b4172951d3d" + }, + { + "logId": "2494886949245166728", + "concreteTypeId": "229f9e763c8424886a0b828eb92ecd7ee7ee60fb9b34ec5595a43cc02b21a6e7" + }, + { + "logId": "13309401912119598731", + "concreteTypeId": "b8b47e85d8cb1e8bd7a47922d6ac2c9aef8c272feb8d5a404e972bb189aeedb3" + }, + { + "logId": "11141065444317510187", + "concreteTypeId": "9a9d03fe63ecba2bda69c30f8c743b0d5719d4dc01ad2cbbedce34332ae57970" + }, + { + "logId": "4883303303013154842", + "concreteTypeId": "43c4fa7b3297401afbf300127e59ea913e5c8f0c7ae69abbec789ab0bb872bed" + }, + { + "logId": "12970362301975156672", + "concreteTypeId": "b3fffbcb3158d7c010c31b194b60fb7857adb4ad61bdcf4b8b42958951d9f308" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "BASE_ASSET_DECIMALS", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 58712 + }, + { + "name": "TOKEN_EXCHANGE_RATE_SCALE", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 58728 + }, + { + "name": "DEFAULT_GAS_AMOUNT", + "concreteTypeId": "1506e6f44c1d6291cdf46395a8e573276a4fa79e8ace3fc891e092ef32d1b0a0", + "offset": 58720 + } + ] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-storage_slots.json new file mode 100644 index 0000000000..d32a7844b1 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster-storage_slots.json @@ -0,0 +1,10 @@ +[ + { + "key": "ccecdaae64d028efc03d6da906d6eac1e11948509e5f9244fc1067951e4b7e91", + "value": "0000000000000001000000000000000000000000000000000000000000000000" + }, + { + "key": "ccecdaae64d028efc03d6da906d6eac1e11948509e5f9244fc1067951e4b7e92", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/gas-paymaster.bin new file mode 100644 index 0000000000000000000000000000000000000000..e05c2cd659c3c04094f5b567412232814a4c971b GIT binary patch literal 60128 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

w3?CW_d}pG~{T8QE^e zoI~_sH~71`QL2T`Kn|jcwHN5AW)AWzC@KXO0RR%TffEtG2_ORj2b6EXz`*NAm(vaO9NO5}00euaGN zkYmuk2+pE#yvtZe8r323(aiapc+Q9OuE4P-=qe_1L9uU?>F;(RFS(NIihiF&^>jKP zN9z)-3;7jivH5%PyBxfavzs1rB~+uSL2U->9@yg}utoY^@MzfM zJ)#~6xg_=hWv-m`d+}C_+z_|a6d%q1j+C34EYDN=>Ai}00~x50ql&r$)domDG_O** zm)U9=->gSkW3Q~e@>((e=7q{=Pfzwmtu?-fX~tfg=|^-HpXO*e|8A3Zand$xHf+2O zHp%!ku=={Sfp1^4Va?TS%|EXD_m>|$bXD_>Ppv(-?%s#*{=>&RzZ`zO<&2eQY`E`l zi+W~{ZhHA>$%BD8pXKruWu;J=J^G(5ZpiTdR z8*XS0tX+RYaCP&VCOrRjUd{R?_w0LW@S<1#dCUDbKKato;y_US}EThK<4ChEVejfos<_uU@;ldA01n{<`(e>sMd1 z{$|Ob9B)n2x;0k^H>~F}p{Ah?8%R8?Ikb+qJTCt|$Nw?=#n=A(x97O(UKFpX<%$12 zd~WIPO<%nH{KdCFRI%{XPj;L+|DC%!^R*7GvHIvw_XWDUo}5^J@8%6ZUi*zpKA-ez z$G5cq96Y?`VD3k^=KS{lyS-yPQ{ULTbJ^CF3xBW7-2L~b-<&=D(S3jOt^D~zJKsL< zhmJk_zIXHo>pRaVe*csAXDwJ>k+*zI$?ml;ob__!yI&vJbH~gF?x{E>GUdQCgR}I} zue|xpO|#A_$t!s7S63_<^WAXv)^T}9UOa2t=4p@rKz~`A@cRp|=svET_4_w&_&ieh zuF^dvJnhl@CN>>^&DQWvc+J;yp1C=D?3T6mIS1BW^UU^prytyV=8NZdZ@8`P%I5-G zCSHBdz9Vmaca7RSz4E2jPiL0Rs{YZE|2%!(7t0=f;mcQ!I%92ne{-boKhd8p{mQ;? z$Hqpz<@&t!FISA!m-HVy{LL->6Z-X!KQ-pmxgL7uKj%%pHSe^EpY5nS`|LeW{^6nF z==s%e-THanA5Psh=d0~My>?vv=7!1Rr#`surR86=d^mjf+}49Hd{CMH;o)1~y7iu{ z$;zKzyI^=#!vTl;r}Oh4eERiYJo)CWum7>9x#0b`K6d>0CtWWuUG)A9ub(;g=402{ zuRnO#Tl-gD`S5E8|NKw;jH~|s=FQQ<|IL4KAoxo4&R_qZFSfpV`M?v;{qHR={OZ#0 zyLLZ*j`!RbZo1>}&BnV&zLg*P+1m%_p3$&l=1a5Y936Yvbx(ac@xe1^4-D#`Uig=P zA6s*KEJ4c z!JQY4FYdoT=eb`FPE!BTxasAq+7GVUQMtD2`@7Y*-Z&l%&d*1q&_j}t0=RH_?$MFx&+k4T>Pqv>Cz2NXa9yxmFEkB!g|5Id4Pw#y-=l+#HKJPbA{p`w{ z^IpF4>szwleyr@2e_ZzbpJv?q#iCo3^4=rI_wAXx_Kw@Of0aG!_3L-rADep3j)@=V zA6WiO^8 z*tOqqegCHI*N3l)4s3h<=tn>3z3q-=OP`&3@Y&mDU$A`5xQ%cAYsZ4nbMGlzw{>1} zX!F)TPPyXjciuSbwT{PvH?5BT<6D1pY+8SKcVpd{?Kh5j)c@V@d~kNz4?9koal>D( z-?i2G?k{gWrR~#eM&15DKRV}tyf9st)r`>bfW_{nrk9>he(;oix3$Hfn&FxqH z;!kgW_s>T+O`EXpwRyMuw*IK=k;-r1e*aJIKlS$$`k$E4bZ61kD?eG4cgMFkvt_@P zIN%@@pnJxyT^G9gnssmdwYRpX*uL$h&sY3>-p_7%MWDn=^BNS-esN(dBl0^zCH}2c z#C3VUytc|~o4oqO6&t<$-_jO&mF, u8)", + "concreteTypeId": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "metadataTypeId": 0 + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "concreteTypeId": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "metadataTypeId": 2 + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MerkleRootMultisigError", + "concreteTypeId": "a9e12ce5428a3a5e60ce6d80348e323f1da0b084f3ba9e8bbe8c226d85c72c8d", + "metadataTypeId": 3 + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MessageIdMultisigError", + "concreteTypeId": "9208f06dcce9a0ccc70f9b9fe484e92b27fb8403737c88adef7279d81fdcc7fe", + "metadataTypeId": 4 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 7 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "f951df7078495f429752af31cbfeda352f61f1a4bf88da5268dc9936b6385012", + "metadataTypeId": 10, + "typeArguments": [ + "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 11 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "type": "u8", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ], + "metadataTypes": [ + { + "type": "(_, _)", + "metadataTypeId": 0, + "components": [ + { + "name": "__tuple_element", + "typeId": 10, + "typeArguments": [ + { + "name": "", + "typeId": 11 + } + ] + }, + { + "name": "__tuple_element", + "typeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b" + } + ] + }, + { + "type": "b256", + "metadataTypeId": 1 + }, + { + "type": "enum interfaces::isms::ism::ModuleType", + "metadataTypeId": 2, + "components": [ + { + "name": "UNUSED", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "ROUTING", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "AGGREGATION", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "LEGACY_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MERKLE_ROOT_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "MESSAGE_ID_MULTISIG", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NULL", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "CCIP_READ", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MerkleRootMultisigError", + "metadataTypeId": 3, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "InvalidMerkleIndexMetadata", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 7 + }, + { + "name": "AlreadyInitialized", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + } + ] + }, + { + "type": "enum interfaces::isms::multisig::multisig_ism::MessageIdMultisigError", + "metadataTypeId": 4, + "components": [ + { + "name": "NoMultisigThreshold", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "NoValidatorMatch", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSigner", + "typeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "name": "FailedToRecoverSignature", + "typeId": 7 + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 5 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 6 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 7, + "components": [ + { + "name": "buf", + "typeId": 8 + }, + { + "name": "len", + "typeId": 12 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 8, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": 12 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 9, + "components": [ + { + "name": "ptr", + "typeId": 6 + }, + { + "name": "cap", + "typeId": 12 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 10, + "components": [ + { + "name": "buf", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 5 + } + ] + }, + { + "name": "len", + "typeId": 12 + } + ], + "typeParameters": [ + 5 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 11, + "components": [ + { + "name": "bits", + "typeId": 1 + } + ] + }, + { + "type": "u64", + "metadataTypeId": 12 + } + ], + "functions": [ + { + "inputs": [], + "name": "module_type", + "output": "4fcafc76b3c7218fc6592123cebdc1b111dcfb70e34f254ca8279c70c0d5fae5", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns an enum that represents the type of security model" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " encoded by this ISM. Relayers infer how to fetch and format metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [ModuleType] - The type of security model." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "verify", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Verifies the message using the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " Assumes the signatures are in the same order as the validators." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - The metadata to be used for verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be verified." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - True if the message is verified successfully." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the threshold is not set or is less than 0." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the signature recovery fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the signer recovery fails." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If no validator matches the signer." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "digest", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the digest to be used for signature verification." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - ABI encoded module metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - Formatted Hyperlane message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Bytes] - The digest to be signed by validators." + ] + } + ] + }, + { + "inputs": [ + { + "name": "metadata", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + }, + { + "name": "index", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "name": "signature_at", + "output": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the signature at a given index from the metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `metadata`: [Bytes] - ABI encoded module metadata." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `index`: [u32] - The index of the signature to be retrieved." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Bytes] - Packed encoding of signature (65 bytes)." + ] + } + ] + }, + { + "inputs": [ + { + "name": "message", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "validators_and_threshold", + "output": "d4da8aeea50e70d476c1f976d23444a72acfe4d9cbbb780710b947b747c1f637", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns the validators and threshold for the Multisig ISM for the given message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `message`: [Bytes] - The message to be processed." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of validators that are set to approve the message." + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [u8] - The threshold of approval for the Multisig ISM." + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validators", + "concreteTypeId": "f951df7078495f429752af31cbfeda352f61f1a4bf88da5268dc9936b6385012" + } + ], + "name": "initialize", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Initializes the contract." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validators`: [Vec] - The list of validators which can approve messages." + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the contract is already initialized." + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "10522924883731128524", + "concreteTypeId": "9208f06dcce9a0ccc70f9b9fe484e92b27fb8403737c88adef7279d81fdcc7fe" + }, + { + "logId": "12241114625345206878", + "concreteTypeId": "a9e12ce5428a3a5e60ce6d80348e323f1da0b084f3ba9e8bbe8c226d85c72c8d" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "THRESHOLD", + "concreteTypeId": "c89951a24c6ca28c13fd1cfdc646b2b656d69e61a92b91023be7eb58eb914b6b", + "offset": 33888 + } + ] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-storage_slots.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism-storage_slots.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/message-id-multisig-ism.bin new file mode 100644 index 0000000000000000000000000000000000000000..b5b2b5590a016ddce9fdbe6abdc56159b6168b61 GIT binary patch literal 33896 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 GrT#BHdrl<) literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-abi.json new file mode 100644 index 0000000000..f5188ba162 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-abi.json @@ -0,0 +1,158 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "()", + "concreteTypeId": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d" + }, + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 1 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 3 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypes": [ + { + "type": "raw untyped ptr", + "metadataTypeId": 0 + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 1, + "components": [ + { + "name": "buf", + "typeId": 2 + }, + { + "name": "len", + "typeId": 4 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 2, + "components": [ + { + "name": "ptr", + "typeId": 0 + }, + { + "name": "cap", + "typeId": 4 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 3, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "u64", + "metadataTypeId": 4 + } + ], + "functions": [ + { + "inputs": [ + { + "name": "_origin", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + }, + { + "name": "_sender", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "name": "_message_body", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "handle", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [], + "name": "interchain_security_module", + "output": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "handled", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [ + { + "name": "module", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54" + } + ], + "name": "set_ism", + "output": "2e38e77b22c314a449e91fafed92a43826ac6aa403ae6a8acb6cf58239fbaf5d", + "attributes": [ + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + } + ], + "loggedTypes": [], + "messagesTypes": [], + "configurables": [] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-storage_slots.json new file mode 100644 index 0000000000..fa3059a3bd --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test-storage_slots.json @@ -0,0 +1,10 @@ +[ + { + "key": "2fbbfd3a0b89bc06c6bbb19927d4cbc5643f7af4970083d5f670aedfa408056f", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + }, + { + "key": "eac52596769876c5f5b1ec43851076adde91edd91cded43b2035126898ec8689", + "value": "0000000000000000000000000000000000000000000000000000000000000000" + } +] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/msg-recipient-test.bin new file mode 100644 index 0000000000000000000000000000000000000000..a23939c08ea879ef0b3122c1d6eb9bef75070cd6 GIT binary patch literal 8168 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 literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-abi.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-abi.json new file mode 100644 index 0000000000..c334e948e5 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-abi.json @@ -0,0 +1,456 @@ +{ + "programType": "contract", + "specVersion": "1", + "encodingVersion": "1", + "concreteTypes": [ + { + "type": "b256", + "concreteTypeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + }, + { + "type": "bool", + "concreteTypeId": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903" + }, + { + "type": "enum interfaces::va::ValidatorAnnounceError", + "concreteTypeId": "ec76592f2dcf24ec6527242afd8946282ac000fffe21a0ed75a797cbf460a556", + "metadataTypeId": 1 + }, + { + "type": "struct interfaces::va::ValidatorAnnouncementEvent", + "concreteTypeId": "d99160a54786c91aa3bfabca957c17df96dbae05a4c79f958b3da89ddc751fbf", + "metadataTypeId": 4 + }, + { + "type": "struct std::bytes::Bytes", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb", + "metadataTypeId": 5 + }, + { + "type": "struct std::contract_id::ContractId", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "metadataTypeId": 7 + }, + { + "type": "struct std::string::String", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c", + "metadataTypeId": 8 + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "metadataTypeId": 10, + "typeArguments": [ + "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + ] + }, + { + "type": "struct std::vec::Vec", + "concreteTypeId": "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8", + "metadataTypeId": 10, + "typeArguments": [ + "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + ] + }, + { + "type": "struct std::vec::Vec>", + "concreteTypeId": "356056ebd0caea5064f10ead20d08a92ad675e09e3fa875f9d632a675fdea875", + "metadataTypeId": 10, + "typeArguments": [ + "44fe2320bc65785fc0e617cb83e9eed432430acbf1a3999783a15982b84237e8" + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2", + "metadataTypeId": 11 + }, + { + "type": "u32", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc" + } + ], + "metadataTypes": [ + { + "type": "()", + "metadataTypeId": 0 + }, + { + "type": "enum interfaces::va::ValidatorAnnounceError", + "metadataTypeId": 1, + "components": [ + { + "name": "ValidatorNotSigner", + "typeId": 0 + }, + { + "name": "ReplayAnnouncement", + "typeId": 0 + } + ] + }, + { + "type": "generic T", + "metadataTypeId": 2 + }, + { + "type": "raw untyped ptr", + "metadataTypeId": 3 + }, + { + "type": "struct interfaces::va::ValidatorAnnouncementEvent", + "metadataTypeId": 4, + "components": [ + { + "name": "validator", + "typeId": 11 + }, + { + "name": "storage_location", + "typeId": 8 + } + ] + }, + { + "type": "struct std::bytes::Bytes", + "metadataTypeId": 5, + "components": [ + { + "name": "buf", + "typeId": 6 + }, + { + "name": "len", + "typeId": 12 + } + ] + }, + { + "type": "struct std::bytes::RawBytes", + "metadataTypeId": 6, + "components": [ + { + "name": "ptr", + "typeId": 3 + }, + { + "name": "cap", + "typeId": 12 + } + ] + }, + { + "type": "struct std::contract_id::ContractId", + "metadataTypeId": 7, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "struct std::string::String", + "metadataTypeId": 8, + "components": [ + { + "name": "bytes", + "typeId": 5 + } + ] + }, + { + "type": "struct std::vec::RawVec", + "metadataTypeId": 9, + "components": [ + { + "name": "ptr", + "typeId": 3 + }, + { + "name": "cap", + "typeId": 12 + } + ], + "typeParameters": [ + 2 + ] + }, + { + "type": "struct std::vec::Vec", + "metadataTypeId": 10, + "components": [ + { + "name": "buf", + "typeId": 9, + "typeArguments": [ + { + "name": "", + "typeId": 2 + } + ] + }, + { + "name": "len", + "typeId": 12 + } + ], + "typeParameters": [ + 2 + ] + }, + { + "type": "struct std::vm::evm::evm_address::EvmAddress", + "metadataTypeId": 11, + "components": [ + { + "name": "bits", + "typeId": "7c5ee1cecf5f8eacd1284feb5f0bf2bdea533a51e2f0c9aabe9236d335989f3b" + } + ] + }, + { + "type": "u64", + "metadataTypeId": 12 + } + ], + "functions": [ + { + "inputs": [ + { + "name": "validator", + "concreteTypeId": "05a44d8c3e00faf7ed545823b7a2b32723545d8715d87a0ab3cf65904948e8d2" + }, + { + "name": "storage_location", + "concreteTypeId": "9a7f1d3e963c10e0a4ea70a8e20a4813d1dc5682e28f74cb102ae50d32f7f98c" + }, + { + "name": "signature", + "concreteTypeId": "cdd87b7d12fe505416570c294c884bca819364863efe3bf539245fa18515fbbb" + } + ], + "name": "announce", + "output": "b760f44fa5965c2474a3b471467a22c43185152129295af588b022ae50b50903", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Announces a validator signature storage location " + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validator`: [b256] - The address of the validator" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `storage_location`: [string] - Information encoding the location of signed checkpoints" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `signature`: [bytes] - The signed validator announcement" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [bool] - Whether the announcement was successful" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Reverts" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the announcement has already been made" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * If the validator is not the signer of the announcement" + ] + }, + { + "name": "storage", + "arguments": [ + "read", + "write" + ] + } + ] + }, + { + "inputs": [ + { + "name": "validators", + "concreteTypeId": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198" + } + ], + "name": "get_announced_storage_locations", + "output": "356056ebd0caea5064f10ead20d08a92ad675e09e3fa875f9d632a675fdea875", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns a list of all announced storage locations " + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Arguments" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * `validators`: [Vec] - The list of validators to get storage locations for" + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + }, + { + "inputs": [], + "name": "get_announced_validators", + "output": "32559685d0c9845f059bf9d472a0a38cf77d36c23dfcffe5489e86a65cdd9198", + "attributes": [ + { + "name": "doc-comment", + "arguments": [ + " Returns a list of validators that have made announcements" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " ### Returns" + ] + }, + { + "name": "doc-comment", + "arguments": [ + "" + ] + }, + { + "name": "doc-comment", + "arguments": [ + " * [Vec] - The list of validators that have made announcements" + ] + }, + { + "name": "storage", + "arguments": [ + "read" + ] + } + ] + } + ], + "loggedTypes": [ + { + "logId": "17038904299369735404", + "concreteTypeId": "ec76592f2dcf24ec6527242afd8946282ac000fffe21a0ed75a797cbf460a556" + }, + { + "logId": "15677418040839293210", + "concreteTypeId": "d99160a54786c91aa3bfabca957c17df96dbae05a4c79f958b3da89ddc751fbf" + } + ], + "messagesTypes": [], + "configurables": [ + { + "name": "LOCAL_DOMAIN", + "concreteTypeId": "d7649d428b9ff33d188ecbf38a7e4d8fd167fa01b2e10fe9a8f9308e52f1d7cc", + "offset": 38440 + }, + { + "name": "MAILBOX_ID", + "concreteTypeId": "29c10735d33b5159f0c71ee1dbd17b36a3e69e41f00fab0d42e1bd9f428d8a54", + "offset": 38448 + } + ] +} \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-storage_slots.json b/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-storage_slots.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce-storage_slots.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce.bin b/rust/main/utils/run-locally/src/fuel/fuel-contracts/validator-announce.bin new file mode 100644 index 0000000000000000000000000000000000000000..65af2d1956051c753cba81aa5ce21adbe750d208 GIT binary patch literal 38992 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≈uno*+GT~%E-S3hj-8;oP1G;P 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 literal 0 HcmV?d00001 diff --git a/rust/main/utils/run-locally/src/fuel/mod.rs b/rust/main/utils/run-locally/src/fuel/mod.rs new file mode 100644 index 0000000000..5e692defff --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/mod.rs @@ -0,0 +1,430 @@ +use deploy::deploy_fuel_hyperlane; +use ethers::types::H160; +use fuels::{ + accounts::wallet::WalletUnlocked, + crypto::SecretKey, + prelude::{FuelService, Provider}, + test_helpers::{ChainConfig, NodeConfig, StateConfig}, + types::{Bits256, Bytes, ContractId}, +}; +use futures::future::join_all; +use macro_rules_attribute::apply; +use std::{ + collections::BTreeMap, + fs, + net::{Ipv4Addr, SocketAddr}, + path::PathBuf, + str::FromStr, + thread::sleep, + time::{Duration, Instant}, +}; + +use tempfile::tempdir; + +use crate::{ + invariants::base_termination_invariants_met, + log, + metrics::agent_balance_sum, + program::Program, + types::{AgentConfig, AgentConfigOut, HyperlaneStack}, + utils::{as_task, concat_path, AgentHandles, TaskHandle}, + AGENT_BIN_PATH, +}; + +mod abis; +mod deploy; +mod types; + +pub use types::*; + +// From fuel_core_chain_config::config::state +pub const FUEL_WALLET_PKS: [&str; 5] = [ + "0xde97d8624a438121b86a1956544bd72ed68cd69f2c99555b08b1e8c51ffd511c", // Deployer - Node 1 + "0x37fa81c84ccd547c30c176b118d5cb892bdb113e8e80141f266519422ef9eefd", // Deployer - Node 2 + "0x862512a2363db2b3a375c0d4bbbd27172180d89f23f2e259bac850ab02619301", // Validator - Node 1 + "0x976e5c3fa620092c718d852ca703b6da9e3075b9f2ecb8ed42d9f746bf26aafb", // Validator - Node 2 + "0x7f8a325504e7315eda997db7861c9447f5c3eff26333b20180475d94443a10c6", +]; + +pub const EVM_VALIDATOR_PKS: [&str; 2] = [ + "0x47e179ec197488593b187f80a00eb0da91f1b9d0b13f8733639f19c30a34926a", // Signer for Validator 1 + "0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba", // Signer for Validator 2 +]; + +pub async fn launch_fuel_node(port: u16) -> eyre::Result { + let mut node_config = NodeConfig::default(); + node_config.addr = SocketAddr::new(Ipv4Addr::new(127, 0, 0, 1).into(), port); + + Ok(FuelService::start( + node_config, + ChainConfig::local_testnet(), + StateConfig::local_testnet(), + ) + .await?) +} + +#[apply(as_task)] +fn launch_fuel_validator( + agent_config: AgentConfig, + agent_config_path: PathBuf, + validator_key: String, + debug: bool, +) -> AgentHandles { + let validator_bin = concat_path(format!("../../{AGENT_BIN_PATH}"), "validator"); + let validator_base = tempdir().expect("Failed to create a temp dir").into_path(); + let validator_base_db = concat_path(&validator_base, "db"); + println!("Validator Base: {:?}", validator_base); + + fs::create_dir_all(&validator_base_db).unwrap(); + println!("Validator DB: {:?}", validator_base_db); + + let checkpoint_path = concat_path(&validator_base, "checkpoint"); + let signature_path = concat_path(&validator_base, "signature"); + Program::default() + .bin(validator_bin) + .working_dir("../../") + .env("CONFIG_FILES", agent_config_path.to_str().unwrap()) + .env( + "MY_VALIDATOR_SIGNATURE_DIRECTORY", + signature_path.to_str().unwrap(), + ) + .env("RUST_BACKTRACE", "1") + .hyp_env("CHECKPOINTSYNCER_PATH", checkpoint_path.to_str().unwrap()) + .hyp_env("CHECKPOINTSYNCER_TYPE", "localStorage") + .hyp_env("ORIGINCHAINNAME", agent_config.name) + .hyp_env("DB", validator_base_db.to_str().unwrap()) + .hyp_env("METRICSPORT", agent_config.metrics_port.to_string()) + .hyp_env("VALIDATOR_KEY", validator_key) // EVM private key + .hyp_env( + "VALIDATOR_PREFIX", + format!("fueltest-{}", agent_config.domain_id), + ) + .hyp_env("SIGNER_SIGNER_TYPE", "hexKey") + .hyp_env("SIGNER_KEY", agent_config.signer.key) // FUEL private key + .hyp_env("TRACING_LEVEL", if debug { "debug" } else { "info" }) + .spawn("VAL", None) +} + +#[apply(as_task)] +fn launch_fuel_relayer( + agent_config_path: String, + relay_chains: Vec, + metrics: u32, + debug: bool, +) -> AgentHandles { + let relayer_bin = concat_path(format!("../../{AGENT_BIN_PATH}"), "relayer"); + let relayer_base = tempdir().unwrap(); + + Program::default() + .bin(relayer_bin) + .working_dir("../../") + .env("CONFIG_FILES", agent_config_path) + .env("RUST_BACKTRACE", "1") + .hyp_env("RELAYCHAINS", relay_chains.join(",")) + .hyp_env("DB", relayer_base.as_ref().to_str().unwrap()) + .hyp_env("ALLOWLOCALCHECKPOINTSYNCERS", "true") + .hyp_env("TRACING_LEVEL", if debug { "debug" } else { "info" }) + .hyp_env("GASPAYMENTENFORCEMENT", "[{\"type\": \"none\"}]") + .hyp_env("METRICSPORT", metrics.to_string()) + .spawn("RLY", None) +} + +#[apply(as_task)] +fn launch_fuel_scraper( + agent_config_path: String, + chains: Vec, + metrics: u32, + debug: bool, +) -> AgentHandles { + let bin = concat_path(format!("../../{AGENT_BIN_PATH}"), "scraper"); + + Program::default() + .bin(bin) + .working_dir("../../") + .env("CONFIG_FILES", agent_config_path) + .env("RUST_BACKTRACE", "1") + .hyp_env("CHAINSTOSCRAPE", chains.join(",")) + .hyp_env( + "DB", + "postgresql://postgres:47221c18c610@localhost:5432/postgres", + ) + .hyp_env("TRACING_LEVEL", if debug { "debug" } else { "info" }) + .hyp_env("METRICSPORT", metrics.to_string()) + .spawn("SCR", None) +} + +#[allow(dead_code)] +async fn run_locally() -> eyre::Result<()> { + const TIMEOUT_SECS: u64 = 60 * 10; + let debug = false; + + // log!("Building rust..."); + Program::new("cargo") + .cmd("build") + .working_dir("../../") + .arg("features", "test-utils") + .arg("bin", "relayer") + .arg("bin", "validator") + .arg("bin", "scraper") + .arg("bin", "init-db") + .filter_logs(|l| !l.contains("workspace-inheritance")) + .run() + .join(); + + let port_start = 42069u16; + let metrics_port_start = 9090u32; + let domain_start = 13373u32; + let node_count = 2; + + log!("Starting Fuel nodes..."); + let nodes_futures = (0..node_count) + .map(|i| async move { + FuelConfig { + node: launch_fuel_node(port_start + i as u16).await.unwrap(), + metrics_port: metrics_port_start + i, + domain: domain_start + i, + } + }) + .collect::>(); + let nodes = join_all(nodes_futures).await; + + log!("Depolying Hyperlane..."); + let nodes = nodes.into_iter().enumerate().map(|(i, config)| async move { + let provider = Provider::from(config.node.bound_address()).await.unwrap(); + assert!(provider.healthy().await.unwrap()); + + let wallet = WalletUnlocked::new_from_private_key( + SecretKey::from_str(FUEL_WALLET_PKS[i]).unwrap(), + Some(provider), + ); + let (target_domain, name, validator_addr) = match config.domain { + 13373 => ( + 13374, + "fueltest1".to_owned(), + H160::from_str("0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc").unwrap(), + ), + 13374 => ( + 13373, + "fueltest2".to_owned(), + H160::from_str("0x15d34aaf54267db7d7c367839aaf71a00a2c6a65").unwrap(), + ), + _ => unreachable!(), + }; + FuelNetwork { + name, + deployments: deploy_fuel_hyperlane( + wallet, + config.domain, + target_domain, + validator_addr, + ) + .await, + config, + } + }); + let nodes = join_all(nodes).await; + + // count all the dispatched messages + let mut dispatched_messages = 0; + + // dispatch the first batch of messages (before agents start) + dispatched_messages += dispatch(&nodes).await; + + let config_dir = tempdir().unwrap(); + let agent_config_out = AgentConfigOut { + chains: nodes + .iter() + .enumerate() + .map(|(i, v)| { + ( + v.name.clone(), + // Local Fuel networks named 1 and 2 + AgentConfig::fuel((i + 1) as u32, FUEL_WALLET_PKS[i], v), + ) + }) + .collect::>(), + }; + + let agent_config_path = concat_path(&config_dir, "config.json"); + fs::write( + &agent_config_path, + serde_json::to_string_pretty(&agent_config_out).unwrap(), + ) + .unwrap(); + + log!("Running postgres db..."); + let postgres = Program::new("docker") + .cmd("run") + .flag("rm") + .arg("name", "scraper-testnet-postgres") + .arg("env", "POSTGRES_PASSWORD=47221c18c610") + .arg("publish", "5432:5432") + .cmd("postgres:14") + .spawn("SQL", None); + + sleep(Duration::from_secs(15)); + + log!("Init postgres db..."); + Program::new(concat_path(format!("../../{AGENT_BIN_PATH}"), "init-db")) + .run() + .join(); + + let hpl_val = agent_config_out + .chains + .clone() + .into_values() + .enumerate() + .map(|(i, agent_config)| { + launch_fuel_validator( + agent_config, + agent_config_path.clone(), + EVM_VALIDATOR_PKS[i].to_owned(), + debug, + ) + }) + .collect::>(); + + let chains = agent_config_out.chains.into_keys().collect::>(); + let path = agent_config_path.to_str().unwrap(); + + let hpl_rly_metrics_port = metrics_port_start + node_count + 1u32; + let hpl_rly = launch_fuel_relayer(path.to_owned(), chains.clone(), hpl_rly_metrics_port, debug); + + let hpl_scr_metrics_port = hpl_rly_metrics_port + 1u32; + let hpl_scr = launch_fuel_scraper(path.to_owned(), chains.clone(), hpl_scr_metrics_port, debug); + + // give things a chance to fully start. + sleep(Duration::from_secs(10)); + + let starting_relayer_balance: f64 = agent_balance_sum(hpl_rly_metrics_port).unwrap(); + + // dispatch the second batch of messages (after agents start) + dispatched_messages += dispatch(&nodes).await; + + let _stack = HyperlaneStack { + validators: hpl_val.into_iter().map(|v| v.join()).collect(), + relayer: hpl_rly.join(), + scraper: hpl_scr.join(), + postgres, + }; + + let loop_start = Instant::now(); + let mut failure_occurred = false; + loop { + // look for the end condition. + if base_termination_invariants_met( + hpl_rly_metrics_port, + hpl_scr_metrics_port, + dispatched_messages, + starting_relayer_balance, + ) + .unwrap_or(false) + { + // end condition reached successfully + break; + } else if (Instant::now() - loop_start).as_secs() > TIMEOUT_SECS { + // we ran out of time + log!("timeout reached before message submission was confirmed"); + failure_occurred = true; + break; + } + + sleep(Duration::from_secs(5)); + } + + if failure_occurred { + stop_fuel_nodes(nodes).await; + panic!("E2E tests failed"); + } else { + log!("E2E tests passed"); + } + + // Stop nodes + stop_fuel_nodes(nodes).await; + + Ok(()) +} + +async fn stop_fuel_nodes(nodes: Vec) { + log!("Stopping Fuel nodes..."); + + join_all(nodes.into_iter().map(|network| async move { + let state = network.config.node.stop().await.unwrap(); + assert!(state.stopped()); + })) + .await; +} + +pub async fn dispatch(nodes: &Vec) -> u32 { + let mut dispatched_messages = 0; + for node in nodes.iter() { + let targets = nodes + .iter() + .filter(|v| v.config.domain != node.config.domain) + .collect::>(); + + for target in targets { + let msg_body = Bytes("Hello, world!".as_bytes().to_vec()); + let recipient = Bits256( + ContractId::from(target.deployments.msg_recipient_test.contract_id()).into(), + ); + + let res = node + .deployments + .mailbox + .methods() + .dispatch( + target.config.domain, + recipient, + msg_body, + Bytes(vec![]), + ContractId::default(), + ) + .determine_missing_contracts(None) + .await + .unwrap() + .call() + .await; + assert!(res.is_ok()); + + let provider = Provider::from(node.config.node.bound_address()) + .await + .unwrap(); + let block = provider + .get_transaction_by_id(&res.unwrap().tx_id.unwrap()) + .await + .unwrap() + .unwrap() + .block_height + .unwrap(); + + log!( + "Dispatched message from {} to {} - at block {}", + node.config.domain, + target.config.domain, + *block + ); + dispatched_messages += 1; + } + } + + log!("Dispatched {} messages", dispatched_messages); + + dispatched_messages +} + +#[cfg(feature = "fuel")] +mod test { + + #[test] + fn test_run() { + use crate::fuel::run_locally; + + tokio::runtime::Builder::new_current_thread() + .enable_all() + .build() + .unwrap() + .block_on(run_locally()) + .unwrap(); + } +} diff --git a/rust/main/utils/run-locally/src/fuel/types.rs b/rust/main/utils/run-locally/src/fuel/types.rs new file mode 100644 index 0000000000..4f91defcdd --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/types.rs @@ -0,0 +1,15 @@ +use fuels::test_helpers::FuelService; + +use super::deploy::FuelDeployments; + +pub struct FuelConfig { + pub node: FuelService, + pub metrics_port: u32, + pub domain: u32, +} + +pub struct FuelNetwork { + pub name: String, + pub config: FuelConfig, + pub deployments: FuelDeployments, +} diff --git a/rust/main/utils/run-locally/src/fuel/utils.rs b/rust/main/utils/run-locally/src/fuel/utils.rs new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/rust/main/utils/run-locally/src/fuel/utils.rs @@ -0,0 +1 @@ + diff --git a/rust/main/utils/run-locally/src/invariants.rs b/rust/main/utils/run-locally/src/invariants.rs index 13fb465b5f..6068d8748c 100644 --- a/rust/main/utils/run-locally/src/invariants.rs +++ b/rust/main/utils/run-locally/src/invariants.rs @@ -1,7 +1,9 @@ +pub use base_termination_invariants::base_termination_invariants_met; pub use common::SOL_MESSAGES_EXPECTED; pub use post_startup_invariants::post_startup_invariants; pub use termination_invariants::termination_invariants_met; +mod base_termination_invariants; mod common; mod post_startup_invariants; mod termination_invariants; diff --git a/rust/main/utils/run-locally/src/invariants/base_termination_invariants.rs b/rust/main/utils/run-locally/src/invariants/base_termination_invariants.rs new file mode 100644 index 0000000000..4c22ce4ff3 --- /dev/null +++ b/rust/main/utils/run-locally/src/invariants/base_termination_invariants.rs @@ -0,0 +1,113 @@ +use maplit::hashmap; + +use crate::{fetch_metric, log, metrics::agent_balance_sum}; + +/// Base termination invariants which should be met for the E2E tests to pass +/// Used by both CosmWasm and Fuel E2E tests +pub fn base_termination_invariants_met( + relayer_metrics_port: u32, + scraper_metrics_port: u32, + messages_expected: u32, + starting_relayer_balance: f64, +) -> eyre::Result { + let expected_gas_payments = messages_expected; + let gas_payments_event_count = fetch_metric( + &relayer_metrics_port.to_string(), + "hyperlane_contract_sync_stored_events", + &hashmap! {"data_type" => "gas_payment"}, + )? + .iter() + .sum::(); + if gas_payments_event_count != expected_gas_payments { + log!( + "Relayer has indexed {} gas payments, expected {}", + gas_payments_event_count, + expected_gas_payments + ); + return Ok(false); + } + + let msg_processed_count = fetch_metric( + &relayer_metrics_port.to_string(), + "hyperlane_operations_processed_count", + &hashmap! {"phase" => "confirmed"}, + )? + .iter() + .sum::(); + if msg_processed_count != messages_expected { + log!( + "Relayer confirmed {} submitted messages, expected {}", + msg_processed_count, + messages_expected + ); + return Ok(false); + } + + let ending_relayer_balance: f64 = agent_balance_sum(relayer_metrics_port).unwrap(); + + // Make sure the balance was correctly updated in the metrics. + // Ideally, make sure that the difference is >= gas_per_tx * gas_cost, set here: + // https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/c2288eb31734ba1f2f997e2c6ecb30176427bc2c/rust/utils/run-locally/src/cosmos/cli.rs#L55 + // @note for CosmWasm + // What's stopping this is that the format returned by the `uosmo` balance query is a surprisingly low number (0.000003999999995184) + // but then maybe the gas_per_tx is just very low - how can we check that? (maybe by simulating said tx) + if starting_relayer_balance <= ending_relayer_balance { + log!( + "Expected starting relayer balance to be greater than ending relayer balance, but got {} <= {}", + starting_relayer_balance, + ending_relayer_balance + ); + return Ok(false); + } + + let dispatched_messages_scraped = fetch_metric( + &scraper_metrics_port.to_string(), + "hyperlane_contract_sync_stored_events", + &hashmap! {"data_type" => "message_dispatch"}, + )? + .iter() + .sum::(); + if dispatched_messages_scraped != messages_expected { + log!( + "Scraper has scraped {} dispatched messages, expected {}", + dispatched_messages_scraped, + messages_expected + ); + return Ok(false); + } + + let gas_payments_scraped = fetch_metric( + &scraper_metrics_port.to_string(), + "hyperlane_contract_sync_stored_events", + &hashmap! {"data_type" => "gas_payment"}, + )? + .iter() + .sum::(); + if gas_payments_scraped != expected_gas_payments { + log!( + "Scraper has scraped {} gas payments, expected {}", + gas_payments_scraped, + expected_gas_payments + ); + return Ok(false); + } + + let delivered_messages_scraped = fetch_metric( + &scraper_metrics_port.to_string(), + "hyperlane_contract_sync_stored_events", + &hashmap! {"data_type" => "message_delivery"}, + )? + .iter() + .sum::(); + if delivered_messages_scraped != messages_expected { + log!( + "Scraper has scraped {} delivered messages, expected {}", + delivered_messages_scraped, + messages_expected + ); + return Ok(false); + } + + log!("Termination invariants have been meet"); + Ok(true) +} diff --git a/rust/main/utils/run-locally/src/main.rs b/rust/main/utils/run-locally/src/main.rs index 7aeb3ae101..9a846212d4 100644 --- a/rust/main/utils/run-locally/src/main.rs +++ b/rust/main/utils/run-locally/src/main.rs @@ -47,11 +47,13 @@ use crate::{ mod config; mod cosmos; mod ethereum; +mod fuel; mod invariants; mod logging; mod metrics; mod program; mod solana; +mod types; mod utils; pub static AGENT_LOGGING_DIR: Lazy<&Path> = Lazy::new(|| { diff --git a/rust/main/utils/run-locally/src/types.rs b/rust/main/utils/run-locally/src/types.rs new file mode 100644 index 0000000000..f8b325b9c5 --- /dev/null +++ b/rust/main/utils/run-locally/src/types.rs @@ -0,0 +1,165 @@ +use std::{collections::BTreeMap, path::PathBuf}; + +use hyperlane_core::NativeToken; +use hyperlane_cosmos::RawCosmosAmount; + +use crate::{ + cosmos::{CosmosNetwork, OsmosisCLI}, + fuel::FuelNetwork, + utils::{cw_to_hex_addr, fuel_to_hex_addr, stop_child, AgentHandles}, +}; + +pub struct HyperlaneStack { + pub validators: Vec, + pub relayer: AgentHandles, + pub scraper: AgentHandles, + pub postgres: AgentHandles, +} + +impl Drop for HyperlaneStack { + fn drop(&mut self) { + for v in &mut self.validators { + stop_child(&mut v.1); + } + stop_child(&mut self.relayer.1); + stop_child(&mut self.scraper.1); + stop_child(&mut self.postgres.1); + } +} + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +pub struct AgentConfigSigner { + #[serde(rename = "type")] + pub typ: String, + pub key: String, + pub prefix: String, +} + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +pub struct AgentConfigIndex { + pub from: u32, + pub chunk: u32, +} + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +pub struct AgentUrl { + pub http: String, +} + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AgentConfig { + pub name: String, + pub domain_id: u32, + pub metrics_port: u32, + pub mailbox: String, + pub interchain_gas_paymaster: String, + pub validator_announce: String, + pub merkle_tree_hook: String, + pub protocol: String, + pub chain_id: String, + pub rpc_urls: Vec, + pub grpc_urls: Vec, + pub bech32_prefix: String, + pub signer: AgentConfigSigner, + pub index: AgentConfigIndex, + pub gas_price: RawCosmosAmount, + pub contract_address_bytes: usize, + pub native_token: NativeToken, +} + +#[derive(serde::Serialize, serde::Deserialize, Clone, Debug)] +pub struct AgentConfigOut { + pub chains: BTreeMap, +} + +impl AgentConfig { + pub fn cosmos(bin: PathBuf, validator: &str, network: &CosmosNetwork) -> Self { + let cli = OsmosisCLI::new(bin, network.launch_resp.home_path.to_str().unwrap()); + let validator = cli.get_keypair(validator); + + AgentConfig { + name: format!("cosmostest{}", network.domain), + domain_id: network.domain, + metrics_port: network.metrics_port, + mailbox: cw_to_hex_addr(&network.deployments.mailbox), + interchain_gas_paymaster: cw_to_hex_addr(&network.deployments.igp), + validator_announce: cw_to_hex_addr(&network.deployments.va), + merkle_tree_hook: cw_to_hex_addr(&network.deployments.hook_merkle), + protocol: "cosmos".to_string(), + chain_id: format!("cosmos-test-{}", network.domain), + rpc_urls: vec![AgentUrl { + http: format!( + "http://{}", + network.launch_resp.endpoint.rpc_addr.replace("tcp://", "") + ), + }], + grpc_urls: vec![ + // The first url points to a nonexistent node, but is used for checking fallback provider logic + AgentUrl { + http: "localhost:1337".to_string(), + }, + AgentUrl { + http: format!("http://{}", network.launch_resp.endpoint.grpc_addr), + }, + ], + bech32_prefix: "osmo".to_string(), + signer: AgentConfigSigner { + typ: "cosmosKey".to_string(), + key: format!("0x{}", hex::encode(validator.priv_key.to_bytes())), + prefix: "osmo".to_string(), + }, + gas_price: RawCosmosAmount { + denom: "uosmo".to_string(), + amount: "0.05".to_string(), + }, + contract_address_bytes: 32, + index: AgentConfigIndex { from: 1, chunk: 5 }, + native_token: NativeToken { + decimals: 6, + denom: "uosmo".to_string(), + }, + } + } + + pub fn fuel(network_index: u32, signer: &str, network: &FuelNetwork) -> Self { + AgentConfig { + name: network.name.clone(), + domain_id: network.config.domain, + metrics_port: network.config.metrics_port, + mailbox: fuel_to_hex_addr(network.deployments.mailbox.contract_id()), + interchain_gas_paymaster: fuel_to_hex_addr( + network.deployments.gas_paymaster.contract_id(), + ), + validator_announce: fuel_to_hex_addr( + network.deployments.validator_announce.contract_id(), + ), + merkle_tree_hook: fuel_to_hex_addr(network.deployments.merkle_tree_hook.contract_id()), + protocol: "fuel".to_string(), + chain_id: format!("fuel-test-{}", network_index), + rpc_urls: vec![AgentUrl { + http: format!( + "http://{}/v1/graphql", + network.config.node.bound_address().to_string() + ), + }], + grpc_urls: vec![], + bech32_prefix: "fuel".to_string(), + signer: AgentConfigSigner { + typ: "hexKey".to_string(), + key: signer.to_string(), + prefix: "0x".to_string(), + }, + gas_price: RawCosmosAmount { + denom: "ETH".to_string(), + amount: "1".to_string(), + }, + contract_address_bytes: 32, + index: AgentConfigIndex { from: 1, chunk: 5 }, + native_token: NativeToken { + decimals: 9, + denom: "ETH".to_string(), + }, + } + } +} diff --git a/rust/main/utils/run-locally/src/utils.rs b/rust/main/utils/run-locally/src/utils.rs index 5e5dd6a126..cf9aac5822 100644 --- a/rust/main/utils/run-locally/src/utils.rs +++ b/rust/main/utils/run-locally/src/utils.rs @@ -6,6 +6,9 @@ use std::process::Child; use std::sync::{Arc, Mutex}; use std::thread::JoinHandle; +use fuels::types::bech32::Bech32ContractId; +use fuels::types::ContractId; +use hyperlane_cosmwasm_interface::types::bech32_decode; use nix::libc::pid_t; use nix::sys::signal; use nix::sys::signal::Signal; @@ -134,3 +137,11 @@ pub fn get_matching_lines(file: &File, search_strings: &[&str]) -> HashMap String { + format!("0x{}", ContractId::from(addr).to_string()) +} + +pub fn cw_to_hex_addr(addr: &str) -> String { + format!("0x{}", hex::encode(bech32_decode(addr).unwrap())) +} From fa03494fc4c8c045ff568e3d16337c638c3ff686 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 19 Feb 2025 12:22:33 +0100 Subject: [PATCH 30/31] feat(fuel): application operation verifier --- rust/main/Cargo.lock | 3 + rust/main/chains/hyperlane-fuel/Cargo.toml | 3 + .../chains/hyperlane-fuel/src/application.rs | 3 + .../src/application/operation_verifier.rs | 70 +++++++++++++++ .../application/operation_verifier/tests.rs | 88 +++++++++++++++++++ rust/main/chains/hyperlane-fuel/src/lib.rs | 2 + .../hyperlane-base/src/settings/chains.rs | 5 +- 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 rust/main/chains/hyperlane-fuel/src/application.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/application/operation_verifier.rs create mode 100644 rust/main/chains/hyperlane-fuel/src/application/operation_verifier/tests.rs diff --git a/rust/main/Cargo.lock b/rust/main/Cargo.lock index eb6f71df5f..c6e3a8beec 100644 --- a/rust/main/Cargo.lock +++ b/rust/main/Cargo.lock @@ -4839,6 +4839,7 @@ dependencies = [ "async-trait", "cynic 3.9.0", "cynic-codegen 3.9.0", + "derive-new", "derive_more 0.99.18", "fuel-core-client", "fuel-core-types", @@ -4846,6 +4847,8 @@ dependencies = [ "futures", "hex 0.4.3", "hyperlane-core", + "hyperlane-operation-verifier", + "hyperlane-warp-route", "reqwest", "serde", "thiserror", diff --git a/rust/main/chains/hyperlane-fuel/Cargo.toml b/rust/main/chains/hyperlane-fuel/Cargo.toml index 9d5a9ff0ba..ac78c5a4df 100644 --- a/rust/main/chains/hyperlane-fuel/Cargo.toml +++ b/rust/main/chains/hyperlane-fuel/Cargo.toml @@ -24,8 +24,11 @@ fuel-core-client.workspace = true fuel-core-types.workspace = true derive_more = { workspace = true, features = ["into", "from"] } reqwest.workspace = true +derive-new.workspace = true +hyperlane-operation-verifier = { path = "../../applications/hyperlane-operation-verifier" } hyperlane-core = { path = "../../hyperlane-core", features = ["async"] } +hyperlane-warp-route = { path = "../../applications/hyperlane-warp-route" } [build-dependencies] abigen = { path = "../../utils/abigen", features = ["fuels"] } diff --git a/rust/main/chains/hyperlane-fuel/src/application.rs b/rust/main/chains/hyperlane-fuel/src/application.rs new file mode 100644 index 0000000000..ec251f30d0 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/application.rs @@ -0,0 +1,3 @@ +pub use operation_verifier::FuelApplicationOperationVerifier; + +mod operation_verifier; diff --git a/rust/main/chains/hyperlane-fuel/src/application/operation_verifier.rs b/rust/main/chains/hyperlane-fuel/src/application/operation_verifier.rs new file mode 100644 index 0000000000..c58c66f266 --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/application/operation_verifier.rs @@ -0,0 +1,70 @@ +use std::io::Cursor; + +use async_trait::async_trait; +use derive_new::new; + +use hyperlane_core::{Decode, HyperlaneMessage, U256}; +use hyperlane_operation_verifier::{ + ApplicationOperationVerifier, ApplicationOperationVerifierReport, +}; +use hyperlane_warp_route::TokenMessage; + +use tracing::trace; + +const WARP_ROUTE_MARKER: &str = "/"; + +/// Application operation verifier for Cosmos +#[derive(new)] +pub struct FuelApplicationOperationVerifier {} + +#[async_trait] +impl ApplicationOperationVerifier for FuelApplicationOperationVerifier { + async fn verify( + &self, + app_context: &Option, + message: &HyperlaneMessage, + ) -> Option { + trace!( + ?app_context, + ?message, + "Fuel application operation verifier", + ); + + Self::verify_message(app_context, message) + } +} + +impl FuelApplicationOperationVerifier { + fn verify_message( + app_context: &Option, + message: &HyperlaneMessage, + ) -> Option { + use ApplicationOperationVerifierReport::{MalformedMessage, ZeroAmount}; + + let context = match app_context { + Some(c) => c, + None => return None, + }; + + if !context.contains(WARP_ROUTE_MARKER) { + return None; + } + + // Starting from this point we assume that we are in a warp route context + + let mut reader = Cursor::new(message.body.as_slice()); + let token_message = match TokenMessage::read_from(&mut reader) { + Ok(m) => m, + Err(_) => return Some(MalformedMessage(message.clone())), + }; + + if token_message.amount() == U256::zero() { + return Some(ZeroAmount); + } + + None + } +} + +#[cfg(test)] +mod tests; diff --git a/rust/main/chains/hyperlane-fuel/src/application/operation_verifier/tests.rs b/rust/main/chains/hyperlane-fuel/src/application/operation_verifier/tests.rs new file mode 100644 index 0000000000..365f9f376c --- /dev/null +++ b/rust/main/chains/hyperlane-fuel/src/application/operation_verifier/tests.rs @@ -0,0 +1,88 @@ +use hyperlane_core::{Encode, HyperlaneMessage, H256, U256}; +use hyperlane_operation_verifier::ApplicationOperationVerifierReport::{ + MalformedMessage, ZeroAmount, +}; +use hyperlane_warp_route::TokenMessage; + +use crate::application::FuelApplicationOperationVerifier; + +#[test] +fn test_app_context_empty() { + // given + let app_context = None; + let message = HyperlaneMessage::default(); + + // when + let report = FuelApplicationOperationVerifier::verify_message(&app_context, &message); + + // then + assert!(report.is_none()); +} + +#[test] +fn test_app_context_not_warp_route() { + // given + let app_context = Some("not-warp-route".to_string()); + let message = HyperlaneMessage::default(); + + // when + let report = FuelApplicationOperationVerifier::verify_message(&app_context, &message); + + // then + assert!(report.is_none()); +} + +#[test] +fn test_message_is_not_token_message() { + // given + let app_context = Some("H/warp-route".to_string()); + let message = HyperlaneMessage::default(); + + // when + let report = FuelApplicationOperationVerifier::verify_message(&app_context, &message); + + // then + assert_eq!(report.unwrap(), MalformedMessage(message)); +} + +#[test] +fn test_token_message_with_zero_amount() { + // given + let app_context = Some("H/warp-route".to_string()); + let token_message = TokenMessage::new(H256::zero(), U256::zero(), vec![]); + let encoded = encode(token_message); + let message = HyperlaneMessage { + body: encoded, + ..Default::default() + }; + + // when + let report = FuelApplicationOperationVerifier::verify_message(&app_context, &message); + + // then + assert_eq!(report.unwrap(), ZeroAmount); +} + +#[test] +fn test_token_message_with_positive_amount() { + // given + let app_context = Some("H/warp-route".to_string()); + let token_message = TokenMessage::new(H256::zero(), U256::one(), vec![]); + let encoded = encode(token_message); + let message = HyperlaneMessage { + body: encoded, + ..Default::default() + }; + + // when + let report = FuelApplicationOperationVerifier::verify_message(&app_context, &message); + + // then + assert!(report.is_none()); +} + +fn encode(token_message: TokenMessage) -> Vec { + let mut encoded = vec![]; + token_message.write_to(&mut encoded).unwrap(); + encoded +} diff --git a/rust/main/chains/hyperlane-fuel/src/lib.rs b/rust/main/chains/hyperlane-fuel/src/lib.rs index 8caf971a5e..e50777e0bd 100644 --- a/rust/main/chains/hyperlane-fuel/src/lib.rs +++ b/rust/main/chains/hyperlane-fuel/src/lib.rs @@ -9,6 +9,8 @@ pub use self::{ }; mod aggregation_ism; +/// Hyperlane Application specific functionality +pub mod application; mod contracts; mod conversions; mod indexer; diff --git a/rust/main/hyperlane-base/src/settings/chains.rs b/rust/main/hyperlane-base/src/settings/chains.rs index 4202d567a2..3620a4cabf 100644 --- a/rust/main/hyperlane-base/src/settings/chains.rs +++ b/rust/main/hyperlane-base/src/settings/chains.rs @@ -205,7 +205,10 @@ impl ChainConf { h_eth::application::EthereumApplicationOperationVerifier::new(), ) as Box), - ChainConnectionConf::Fuel(_) => todo!(), + ChainConnectionConf::Fuel(_conf) => Ok(Box::new( + h_fuel::application::FuelApplicationOperationVerifier::new(), + ) + as Box), ChainConnectionConf::Sealevel(conf) => { let provider = h_sealevel::SealevelProvider::new(locator.domain.clone(), conf); let verifier = From b7050b5ec30123253b08ad0e9b28e7fe2732cae8 Mon Sep 17 00:00:00 2001 From: "Mantas M." Date: Wed, 19 Feb 2025 12:39:39 +0100 Subject: [PATCH 31/31] fix(fuel): move reorg warning to conf builder --- rust/main/agents/relayer/src/relayer.rs | 1 - rust/main/agents/scraper/src/agent.rs | 1 - rust/main/agents/validator/src/validator.rs | 1 - rust/main/hyperlane-base/src/settings/base.rs | 12 -------- .../src/settings/parser/connection_parser.rs | 29 +++++++++++++++---- .../hyperlane-base/src/settings/parser/mod.rs | 1 + 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/rust/main/agents/relayer/src/relayer.rs b/rust/main/agents/relayer/src/relayer.rs index bca3c48c3e..d72edd5c1b 100644 --- a/rust/main/agents/relayer/src/relayer.rs +++ b/rust/main/agents/relayer/src/relayer.rs @@ -138,7 +138,6 @@ impl BaseAgent for Relayer { .map(|origin| (origin.clone(), HyperlaneRocksDB::new(origin, db.clone()))) .collect::>(); - settings.check_fuel_reorg(); let application_operation_verifiers = Self::build_application_operation_verifiers(&settings, &core_metrics, &chain_metrics) .await; diff --git a/rust/main/agents/scraper/src/agent.rs b/rust/main/agents/scraper/src/agent.rs index 886499e914..2d749a234f 100644 --- a/rust/main/agents/scraper/src/agent.rs +++ b/rust/main/agents/scraper/src/agent.rs @@ -53,7 +53,6 @@ impl BaseAgent for Scraper { Self: Sized, { let db = ScraperDb::connect(&settings.db).await?; - settings.check_fuel_reorg(); let core = settings.build_hyperlane_core(metrics.clone()); let contract_sync_metrics = Arc::new(ContractSyncMetrics::new(&metrics)); diff --git a/rust/main/agents/validator/src/validator.rs b/rust/main/agents/validator/src/validator.rs index 230c1ad605..76dfbbd21f 100644 --- a/rust/main/agents/validator/src/validator.rs +++ b/rust/main/agents/validator/src/validator.rs @@ -76,7 +76,6 @@ impl BaseAgent for Validator { // Intentionally using hyperlane_ethereum for the validator's signer let (signer_instance, signer) = SingletonSigner::new(settings.validator.build().await?); - settings.check_fuel_reorg(); let core = settings.build_hyperlane_core(metrics.clone()); // Be extra sure to panic checkpoint syncer fails, which indicates // a fatal startup error. diff --git a/rust/main/hyperlane-base/src/settings/base.rs b/rust/main/hyperlane-base/src/settings/base.rs index 8ec566da64..6e87483e25 100644 --- a/rust/main/hyperlane-base/src/settings/base.rs +++ b/rust/main/hyperlane-base/src/settings/base.rs @@ -84,18 +84,6 @@ impl Settings { .ok_or_else(|| eyre!("No chain setup found for {domain}")) } - /// Check and warn if reorg period is set for FuelVM domains. - pub fn check_fuel_reorg(&self) { - self.chains.values().for_each(|conf| { - if conf.domain.domain_protocol() == HyperlaneDomainProtocol::Fuel && !conf.reorg_period.is_none() { - warn!( - "Reorg period is set for fuel domain {:?}. FuelVM chains are implemented with instant finality", - conf.domain - ); - } - }); - } - /// Try to get the domain for a given chain by name. pub fn lookup_domain(&self, chain_name: &str) -> Result { self.chains diff --git a/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs b/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs index aecf9737fb..ea1f1670b7 100644 --- a/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs +++ b/rust/main/hyperlane-base/src/settings/parser/connection_parser.rs @@ -1,7 +1,9 @@ use eyre::eyre; +use hyperlane_core::ReorgPeriod; use hyperlane_sealevel::{ HeliusPriorityFeeLevel, HeliusPriorityFeeOracleConfig, PriorityFeeOracleConfig, }; +use tracing::warn; use url::Url; use h_eth::TransactionOverrides; @@ -186,6 +188,25 @@ fn build_sealevel_connection_conf( } } +fn build_fuel_connection_conf( + rpcs: &[Url], + operation_batch: OperationBatchConfig, + reorg: &ReorgPeriod, +) -> Option { + if !reorg.is_none() { + warn!( + "Reorg period set for FuelVM domain will be ignored. FuelVM chains are implemented with instant finality" + ); + } + + rpcs.iter().next().map(|url| { + ChainConnectionConf::Fuel(h_fuel::ConnectionConf { + url: url.clone(), + operation_batch, + }) + }) +} + fn parse_native_token( chain: &ValueParser, err: &mut ConfigParsingError, @@ -359,6 +380,7 @@ pub fn build_connection_conf( err: &mut ConfigParsingError, default_rpc_consensus_type: &str, operation_batch: OperationBatchConfig, + reorg: &ReorgPeriod, ) -> Option { match domain_protocol { HyperlaneDomainProtocol::Ethereum => build_ethereum_connection_conf( @@ -368,12 +390,7 @@ pub fn build_connection_conf( default_rpc_consensus_type, operation_batch, ), - HyperlaneDomainProtocol::Fuel => rpcs.iter().next().map(|url| { - ChainConnectionConf::Fuel(h_fuel::ConnectionConf { - url: url.clone(), - operation_batch, - }) - }), + HyperlaneDomainProtocol::Fuel => build_fuel_connection_conf(rpcs, operation_batch, reorg), HyperlaneDomainProtocol::Sealevel => rpcs .iter() .next() diff --git a/rust/main/hyperlane-base/src/settings/parser/mod.rs b/rust/main/hyperlane-base/src/settings/parser/mod.rs index d176ad857b..7da401171e 100644 --- a/rust/main/hyperlane-base/src/settings/parser/mod.rs +++ b/rust/main/hyperlane-base/src/settings/parser/mod.rs @@ -215,6 +215,7 @@ fn parse_chain( batch_contract_address, max_batch_size, }, + &reorg_period, ); cfg_unwrap_all!(&chain.cwp, err: [connection, mailbox, interchain_gas_paymaster, validator_announce, merkle_tree_hook]);