diff --git a/.changelog/unreleased/features/4082-ibc-pfm.md b/.changelog/unreleased/features/4082-ibc-pfm.md new file mode 100644 index 0000000000..5aebd47ffc --- /dev/null +++ b/.changelog/unreleased/features/4082-ibc-pfm.md @@ -0,0 +1,3 @@ +- Implement compatibility with Strangelove's Packet Forward Middleware + in Namada, to allow forwarding ICS-20 packets over multiple chains. + ([\#4082](https://github.com/anoma/namada/pull/4082)) \ No newline at end of file diff --git a/.github/workflows/scripts/e2e.json b/.github/workflows/scripts/e2e.json index 51ac256df2..77f03765a1 100644 --- a/.github/workflows/scripts/e2e.json +++ b/.github/workflows/scripts/e2e.json @@ -6,6 +6,8 @@ "e2e::ibc_tests::fee_payment_with_ibc_token": 357, "e2e::ibc_tests::ibc_token_inflation": 840, "e2e::ibc_tests::ibc_rate_limit": 485, + "e2e::ibc_tests::ibc_pfm_happy_flows": 485, + "e2e::ibc_tests::ibc_pfm_unhappy_flows": 485, "e2e::ibc_tests::ibc_upgrade_client": 280, "e2e::eth_bridge_tests::test_add_to_bridge_pool": 10, "e2e::ledger_tests::double_signing_gets_slashed": 12, diff --git a/Cargo.lock b/Cargo.lock index 7861b507ae..fa3dea77b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1892,6 +1892,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +[[package]] +name = "dur" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5b6c91b5e394b75cd96c36393fc938496c030220207a0ccf34d6cd313d3b49" +dependencies = [ + "nom", + "rust_decimal", +] + [[package]] name = "duration-str" version = "0.10.0" @@ -3336,7 +3346,7 @@ dependencies = [ [[package]] name = "ibc" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-apps", "ibc-clients", @@ -3349,7 +3359,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer-types", "ibc-core", @@ -3359,7 +3369,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "base64 0.22.1", @@ -3381,7 +3391,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-transfer-types", "ibc-core", @@ -3391,7 +3401,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3410,7 +3420,7 @@ dependencies = [ [[package]] name = "ibc-apps" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer", "ibc-app-transfer", @@ -3419,7 +3429,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "ibc-client-tendermint-types", @@ -3436,7 +3446,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "displaydoc", "ibc-core-client-types", @@ -3453,7 +3463,7 @@ dependencies = [ [[package]] name = "ibc-client-wasm-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "base64 0.22.1", "displaydoc", @@ -3467,7 +3477,7 @@ dependencies = [ [[package]] name = "ibc-clients" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-tendermint", "ibc-client-wasm-types", @@ -3476,7 +3486,7 @@ dependencies = [ [[package]] name = "ibc-core" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -3492,7 +3502,7 @@ dependencies = [ [[package]] name = "ibc-core-channel" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel-types", "ibc-core-client", @@ -3507,7 +3517,7 @@ dependencies = [ [[package]] name = "ibc-core-channel-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3531,7 +3541,7 @@ dependencies = [ [[package]] name = "ibc-core-client" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-client-context", "ibc-core-client-types", @@ -3544,7 +3554,7 @@ dependencies = [ [[package]] name = "ibc-core-client-context" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -3560,7 +3570,7 @@ dependencies = [ [[package]] name = "ibc-core-client-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3581,7 +3591,7 @@ dependencies = [ [[package]] name = "ibc-core-commitment-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3601,7 +3611,7 @@ dependencies = [ [[package]] name = "ibc-core-connection" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-wasm-types", "ibc-core-client", @@ -3615,7 +3625,7 @@ dependencies = [ [[package]] name = "ibc-core-connection-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3637,7 +3647,7 @@ dependencies = [ [[package]] name = "ibc-core-handler" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -3652,7 +3662,7 @@ dependencies = [ [[package]] name = "ibc-core-handler-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3677,7 +3687,7 @@ dependencies = [ [[package]] name = "ibc-core-host" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -3695,7 +3705,7 @@ dependencies = [ [[package]] name = "ibc-core-host-cosmos" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -3718,7 +3728,7 @@ dependencies = [ [[package]] name = "ibc-core-host-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3734,7 +3744,7 @@ dependencies = [ [[package]] name = "ibc-core-router" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -3748,7 +3758,7 @@ dependencies = [ [[package]] name = "ibc-core-router-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -3767,17 +3777,36 @@ dependencies = [ [[package]] name = "ibc-derive" version = "0.8.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "proc-macro2", "quote", "syn 2.0.52", ] +[[package]] +name = "ibc-middleware-packet-forward" +version = "0.6.0" +source = "git+https://github.com/heliaxdev/ibc-middleware?tag=pfm/v0.6.0#ca824cfbe550c529d30bf27a97026dd0a058cfdf" +dependencies = [ + "borsh", + "dur", + "either", + "ibc-app-transfer-types", + "ibc-core-channel", + "ibc-core-channel-types", + "ibc-core-host-types", + "ibc-core-router", + "ibc-core-router-types", + "ibc-primitives", + "serde", + "serde_json", +] + [[package]] name = "ibc-primitives" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "arbitrary", "borsh", @@ -3818,7 +3847,7 @@ dependencies = [ [[package]] name = "ibc-query" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "displaydoc", "ibc", @@ -3829,7 +3858,7 @@ dependencies = [ [[package]] name = "ibc-testkit" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "basecoin-store", "derive_more", @@ -5060,8 +5089,10 @@ dependencies = [ "assert_matches", "borsh", "data-encoding", + "dur", "ibc", "ibc-derive", + "ibc-middleware-packet-forward", "ibc-testkit", "ics23", "konst", @@ -5495,12 +5526,14 @@ dependencies = [ "concat-idents", "data-encoding", "derivative", + "dur", "escargot", "expectrl", "eyre", "flate2", "fs_extra", "hyper 0.14.27", + "ibc-middleware-packet-forward", "ibc-testkit", "ics23", "itertools 0.12.1", @@ -7283,12 +7316,18 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", + "borsh", + "bytes", "num-traits 0.2.17", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", ] [[package]] @@ -7678,11 +7717,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/Cargo.toml b/Cargo.toml index c6699f1ce5..f68394740b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -99,6 +99,7 @@ derivation-path = "0.2.0" derivative = "2.2.0" directories = "4.0.1" drain_filter_polyfill = "0.1.3" +dur = "0.5.3" duration-str = "0.10.0" ed25519-consensus = "2.1.0" either = "1.12.0" @@ -118,9 +119,10 @@ fs_extra = "1.2.0" futures = "0.3" git2 = { version = "0.18.1", default-features = false } # branch yuji/derive-arbitrary -ibc = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "38bd2a32f35117d4d9165a3c68c64ccd87ad56dd", features = ["serde"] } -ibc-derive = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" } -ibc-testkit = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "38bd2a32f35117d4d9165a3c68c64ccd87ad56dd", default-features = false } +ibc = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "aa229566e6bb688cc2626dab276c3849abc0c583", features = ["serde"] } +ibc-derive = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "aa229566e6bb688cc2626dab276c3849abc0c583" } +ibc-middleware-packet-forward = { git = "https://github.com/heliaxdev/ibc-middleware", tag = "pfm/v0.6.0", features = ["borsh"] } +ibc-testkit = { git = "https://github.com/heliaxdev/cosmos-ibc-rs", rev = "aa229566e6bb688cc2626dab276c3849abc0c583", default-features = false } ics23 = "0.12.0" index-set = { git = "https://github.com/heliaxdev/index-set", tag = "v0.8.1", features = ["serialize-borsh", "serialize-serde"] } indexmap = { git = "https://github.com/heliaxdev/indexmap", tag = "2.2.4-heliax-1", features = ["borsh-schema", "serde"] } @@ -173,7 +175,7 @@ rpassword = "5.0.1" rustversion = "1.0" serde = {version = "1.0.125", features = ["derive"]} serde_bytes = "0.11.5" -serde_json = "1.0.62" +serde_json = "1.0.133" serde_tuple = "0.5.0" sha2 = "0.9.3" sha2-const = "0.1.2" diff --git a/crates/benches/native_vps.rs b/crates/benches/native_vps.rs index f2350ca722..13553332f3 100644 --- a/crates/benches/native_vps.rs +++ b/crates/benches/native_vps.rs @@ -23,6 +23,7 @@ use namada_apps_lib::governance::pgf::storage::steward::StewardDetail; use namada_apps_lib::governance::storage::proposal::ProposalType; use namada_apps_lib::governance::storage::vote::ProposalVote; use namada_apps_lib::governance::{InitProposalData, VoteProposalData}; +use namada_apps_lib::ibc::context::pfm_mod::PfmTransferModule; use namada_apps_lib::ibc::core::channel::types::channel::Order; use namada_apps_lib::ibc::core::channel::types::msgs::MsgChannelOpenInit; use namada_apps_lib::ibc::core::channel::types::Version as ChannelVersion; @@ -34,9 +35,7 @@ use namada_apps_lib::ibc::core::host::types::identifiers::{ ClientId, ConnectionId, PortId, }; use namada_apps_lib::ibc::primitives::ToProto; -use namada_apps_lib::ibc::{ - IbcActions, NftTransferModule, TransferModule, COMMITMENT_PREFIX, -}; +use namada_apps_lib::ibc::{IbcActions, NftTransferModule, COMMITMENT_PREFIX}; use namada_apps_lib::masp_primitives::merkle_tree::CommitmentTree; use namada_apps_lib::masp_primitives::transaction::Transaction; use namada_apps_lib::masp_proofs::sapling::SaplingVerificationContextInner; @@ -1718,7 +1717,10 @@ fn ibc_vp_validate_action(c: &mut Criterion) { ); actions.set_validation_params(ibc.validation_params().unwrap()); - let module = TransferModule::new(ctx.clone(), verifiers); + let module = PfmTransferModule::<_, parameters::Store<_>>::wrap( + ctx.clone(), + verifiers, + ); actions.add_transfer_module(module); let module = NftTransferModule::<_, token::Store<()>>::new(ctx); actions.add_transfer_module(module); @@ -1779,7 +1781,10 @@ fn ibc_vp_execute_action(c: &mut Criterion) { ); actions.set_validation_params(ibc.validation_params().unwrap()); - let module = TransferModule::new(ctx.clone(), verifiers); + let module = PfmTransferModule::<_, parameters::Store<_>>::wrap( + ctx.clone(), + verifiers, + ); actions.add_transfer_module(module); let module = NftTransferModule::<_, token::Store<()>>::new(ctx); actions.add_transfer_module(module); diff --git a/crates/ibc/Cargo.toml b/crates/ibc/Cargo.toml index 39f0c77965..f520e810c3 100644 --- a/crates/ibc/Cargo.toml +++ b/crates/ibc/Cargo.toml @@ -40,10 +40,12 @@ namada_vp = { path = "../vp" } arbitrary = { workspace = true, optional = true } borsh.workspace = true data-encoding.workspace = true +dur.workspace = true konst.workspace = true linkme = {workspace = true, optional = true} ibc.workspace = true ibc-derive.workspace = true +ibc-middleware-packet-forward.workspace = true ibc-testkit = {workspace = true, optional = true} ics23.workspace = true masp_primitives.workspace = true diff --git a/crates/ibc/src/context/common.rs b/crates/ibc/src/context/common.rs index 7f920d8cb3..35233fd70e 100644 --- a/crates/ibc/src/context/common.rs +++ b/crates/ibc/src/context/common.rs @@ -576,14 +576,11 @@ pub trait IbcCommonContext: IbcStorageContext { port_id: &PortId, channel_id: &ChannelId, sequence: Sequence, - ) -> Result { + ) -> Result> { let key = storage::ack_key(port_id, channel_id, sequence); match self.storage().read_bytes(&key)? { - Some(value) => Ok(value.into()), - None => { - Err(PacketError::PacketAcknowledgementNotFound { sequence } - .into()) - } + Some(value) => Ok(Some(value.into())), + None => Ok(None), } } diff --git a/crates/ibc/src/context/mod.rs b/crates/ibc/src/context/mod.rs index d6e238c6c9..89a82b13e7 100644 --- a/crates/ibc/src/context/mod.rs +++ b/crates/ibc/src/context/mod.rs @@ -5,6 +5,7 @@ pub mod common; pub mod execution; pub mod nft_transfer; pub mod nft_transfer_mod; +pub mod pfm_mod; pub mod router; pub mod storage; pub mod token_transfer; diff --git a/crates/ibc/src/context/nft_transfer_mod.rs b/crates/ibc/src/context/nft_transfer_mod.rs index 420d80362e..b8450468ce 100644 --- a/crates/ibc/src/context/nft_transfer_mod.rs +++ b/crates/ibc/src/context/nft_transfer_mod.rs @@ -261,7 +261,7 @@ where &mut self, packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { on_recv_packet_execute(&mut self.ctx, packet) } @@ -482,10 +482,10 @@ pub mod testing { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { ( ModuleExtras::empty(), - AcknowledgementStatus::success(ack_success_b64()).into(), + Some(AcknowledgementStatus::success(ack_success_b64()).into()), ) } diff --git a/crates/ibc/src/context/pfm_mod.rs b/crates/ibc/src/context/pfm_mod.rs new file mode 100644 index 0000000000..49d7e53cf4 --- /dev/null +++ b/crates/ibc/src/context/pfm_mod.rs @@ -0,0 +1,526 @@ +//! Implementation of Packet Forward Middleware on top of the ICS-20 +//! [`TransferModule`]. + +use std::cell::RefCell; +use std::collections::BTreeSet; +use std::fmt::{Debug, Formatter}; +use std::marker::PhantomData; +use std::rc::Rc; + +use ibc::apps::transfer::context::TokenTransferExecutionContext; +use ibc::apps::transfer::handler::{ + refund_packet_token_execute, send_transfer_execute, +}; +use ibc::apps::transfer::types::msgs::transfer::MsgTransfer; +use ibc::apps::transfer::types::packet::PacketData; +use ibc::apps::transfer::types::{is_receiver_chain_source, TracePrefix}; +use ibc::core::channel::handler::{ + commit_packet_acknowledgment, emit_packet_acknowledgement_event, +}; +use ibc::core::channel::types::acknowledgement::Acknowledgement; +use ibc::core::channel::types::channel::{Counterparty, Order}; +use ibc::core::channel::types::error::{ChannelError, PacketError}; +use ibc::core::channel::types::packet::Packet; +use ibc::core::channel::types::timeout::TimeoutTimestamp; +use ibc::core::channel::types::Version; +use ibc::core::host::types::identifiers::{ + ChannelId, ConnectionId, PortId, Sequence, +}; +use ibc::core::router::module::Module; +use ibc::core::router::types::module::{ModuleExtras, ModuleId}; +use ibc::primitives::Signer; +use ibc_middleware_packet_forward::{ + InFlightPacket, InFlightPacketKey, PacketForwardMiddleware, PfmContext, +}; +use namada_core::address::{Address, IBC as IBC_ADDRESS, MULTITOKEN}; +use namada_core::storage::{self, KeySeg}; +use namada_state::{StorageRead, StorageWrite}; + +use crate::context::transfer_mod::TransferModule; +use crate::context::IbcContext; +use crate::{ + Error, IbcCommonContext, IbcStorageContext, ModuleWrapper, + TokenTransferContext, +}; + +const MIDDLEWARES_SUBKEY: &str = "middleware"; +const PFM_SUBKEY: &str = "pfm"; + +/// Get the Namada storage key associated to the provided `InFlightPacketKey`. +pub fn get_inflight_packet_key( + inflight_packet_key: &InFlightPacketKey, +) -> storage::Key { + let key: storage::Key = IBC_ADDRESS.to_db_key().into(); + key.with_segment(MIDDLEWARES_SUBKEY.to_string()) + .with_segment(PFM_SUBKEY.to_string()) + .with_segment(inflight_packet_key.port.to_string()) + .with_segment(inflight_packet_key.channel.to_string()) + .with_segment(inflight_packet_key.sequence.to_string()) +} + +/// A wrapper around an IBC transfer module necessary to +/// build execution contexts. This allows us to implement +/// packet forward middleware on this struct. +pub struct PfmTransferModule +where + C: IbcCommonContext + Debug, +{ + /// The main module + pub transfer_module: TransferModule, + #[allow(missing_docs)] + pub _phantom: PhantomData, +} + +impl PfmTransferModule +where + C: IbcCommonContext + Debug, +{ + /// Create a new [`PfmTransferModule`] + pub fn wrap( + ctx: Rc>, + verifiers: Rc>>, + ) -> PacketForwardMiddleware { + PacketForwardMiddleware::next(Self { + transfer_module: TransferModule::new(ctx, verifiers), + _phantom: Default::default(), + }) + } +} + +impl Debug + for PfmTransferModule +{ + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_struct(stringify!(PfmTransferModule)) + .field("transfer_module", &self.transfer_module) + .finish_non_exhaustive() + } +} + +impl Module for PfmTransferModule +where + C: IbcCommonContext + Debug, +{ + fn on_chan_open_init_validate( + &self, + order: Order, + connection_hops: &[ConnectionId], + port_id: &PortId, + channel_id: &ChannelId, + counterparty: &Counterparty, + version: &Version, + ) -> Result { + self.transfer_module.on_chan_open_init_validate( + order, + connection_hops, + port_id, + channel_id, + counterparty, + version, + ) + } + + fn on_chan_open_init_execute( + &mut self, + order: Order, + connection_hops: &[ConnectionId], + port_id: &PortId, + channel_id: &ChannelId, + counterparty: &Counterparty, + version: &Version, + ) -> Result<(ModuleExtras, Version), ChannelError> { + self.transfer_module.on_chan_open_init_execute( + order, + connection_hops, + port_id, + channel_id, + counterparty, + version, + ) + } + + fn on_chan_open_try_validate( + &self, + order: Order, + connection_hops: &[ConnectionId], + port_id: &PortId, + channel_id: &ChannelId, + counterparty: &Counterparty, + counterparty_version: &Version, + ) -> Result { + self.transfer_module.on_chan_open_try_validate( + order, + connection_hops, + port_id, + channel_id, + counterparty, + counterparty_version, + ) + } + + fn on_chan_open_try_execute( + &mut self, + order: Order, + connection_hops: &[ConnectionId], + port_id: &PortId, + channel_id: &ChannelId, + counterparty: &Counterparty, + counterparty_version: &Version, + ) -> Result<(ModuleExtras, Version), ChannelError> { + self.transfer_module.on_chan_open_try_execute( + order, + connection_hops, + port_id, + channel_id, + counterparty, + counterparty_version, + ) + } + + fn on_chan_open_ack_validate( + &self, + port_id: &PortId, + channel_id: &ChannelId, + counterparty_version: &Version, + ) -> Result<(), ChannelError> { + self.transfer_module.on_chan_open_ack_validate( + port_id, + channel_id, + counterparty_version, + ) + } + + fn on_chan_open_ack_execute( + &mut self, + port_id: &PortId, + channel_id: &ChannelId, + counterparty_version: &Version, + ) -> Result { + self.transfer_module.on_chan_open_ack_execute( + port_id, + channel_id, + counterparty_version, + ) + } + + fn on_chan_open_confirm_validate( + &self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result<(), ChannelError> { + self.transfer_module + .on_chan_open_confirm_validate(port_id, channel_id) + } + + fn on_chan_open_confirm_execute( + &mut self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result { + self.transfer_module + .on_chan_open_confirm_execute(port_id, channel_id) + } + + fn on_chan_close_init_validate( + &self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result<(), ChannelError> { + self.transfer_module + .on_chan_close_init_validate(port_id, channel_id) + } + + fn on_chan_close_init_execute( + &mut self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result { + self.transfer_module + .on_chan_close_init_execute(port_id, channel_id) + } + + fn on_chan_close_confirm_validate( + &self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result<(), ChannelError> { + self.transfer_module + .on_chan_close_confirm_validate(port_id, channel_id) + } + + fn on_chan_close_confirm_execute( + &mut self, + port_id: &PortId, + channel_id: &ChannelId, + ) -> Result { + self.transfer_module + .on_chan_close_confirm_execute(port_id, channel_id) + } + + fn on_recv_packet_execute( + &mut self, + packet: &Packet, + relayer: &Signer, + ) -> (ModuleExtras, Option) { + self.transfer_module.on_recv_packet_execute(packet, relayer) + } + + fn on_acknowledgement_packet_validate( + &self, + packet: &Packet, + acknowledgement: &Acknowledgement, + relayer: &Signer, + ) -> Result<(), PacketError> { + self.transfer_module.on_acknowledgement_packet_validate( + packet, + acknowledgement, + relayer, + ) + } + + fn on_acknowledgement_packet_execute( + &mut self, + packet: &Packet, + acknowledgement: &Acknowledgement, + relayer: &Signer, + ) -> (ModuleExtras, Result<(), PacketError>) { + self.transfer_module.on_acknowledgement_packet_execute( + packet, + acknowledgement, + relayer, + ) + } + + fn on_timeout_packet_validate( + &self, + packet: &Packet, + relayer: &Signer, + ) -> Result<(), PacketError> { + self.transfer_module + .on_timeout_packet_validate(packet, relayer) + } + + fn on_timeout_packet_execute( + &mut self, + packet: &Packet, + relayer: &Signer, + ) -> (ModuleExtras, Result<(), PacketError>) { + self.transfer_module + .on_timeout_packet_execute(packet, relayer) + } +} + +impl PfmContext for PfmTransferModule +where + C: IbcCommonContext + Debug, + Params: namada_systems::parameters::Read<::Storage>, +{ + type Error = crate::Error; + + fn send_transfer_execute( + &mut self, + msg: MsgTransfer, + ) -> Result { + let seq = self + .transfer_module + .ctx + .inner + .borrow() + .get_next_sequence_send(&msg.port_id_on_a, &msg.chan_id_on_a) + .map_err(|e| Error::Context(Box::new(e)))?; + tracing::debug!(?seq, ?msg, "PFM send_transfer_execute"); + + let mut ctx = IbcContext::::new( + self.transfer_module.ctx.inner.clone(), + ); + let mut token_transfer_ctx = TokenTransferContext::new( + self.transfer_module.ctx.inner.clone(), + Default::default(), + ); + + send_transfer_execute(&mut ctx, &mut token_transfer_ctx, msg) + .map_err(Error::TokenTransfer)?; + Ok(seq) + } + + fn receive_refund_execute( + &mut self, + packet: &Packet, + data: PacketData, + ) -> Result<(), Self::Error> { + tracing::debug!(?packet, ?data, "PFM receive_refund_execute"); + let mut token_transfer_ctx = TokenTransferContext::new( + self.transfer_module.ctx.inner.clone(), + self.transfer_module.ctx.verifiers.clone(), + ); + self.transfer_module.ctx.insert_verifier(&MULTITOKEN); + refund_packet_token_execute(&mut token_transfer_ctx, packet, &data) + .map_err(Error::TokenTransfer) + } + + fn send_refund_execute( + &mut self, + msg: &InFlightPacket, + ) -> Result<(), Self::Error> { + tracing::debug!(?msg, "PFM send_refund_execute"); + + let packet_data: PacketData = serde_json::from_slice(&msg.packet_data) + .expect( + "The in-flight packet data should have belonged to an ICS-20 \ + packet", + ); + + let mut token_transfer_ctx = TokenTransferContext::new( + self.transfer_module.ctx.inner.clone(), + self.transfer_module.ctx.verifiers.clone(), + ); + + self.transfer_module.ctx.insert_verifier(&MULTITOKEN); + + if is_receiver_chain_source( + msg.packet_src_port_id.clone(), + msg.packet_src_channel_id.clone(), + &packet_data.token.denom, + ) { + let coin = { + let mut c = packet_data.token; + c.denom.remove_trace_prefix(&TracePrefix::new( + msg.packet_src_port_id.clone(), + msg.packet_src_channel_id.clone(), + )); + c + }; + + token_transfer_ctx + .escrow_coins_execute( + &IBC_ADDRESS, + &msg.refund_port_id, + &msg.refund_channel_id, + &coin, + &String::new().into(), + ) + .map_err(Error::TokenTransfer) + } else { + let coin = { + let mut c = packet_data.token; + c.denom.add_trace_prefix(TracePrefix::new( + msg.refund_port_id.clone(), + msg.refund_channel_id.clone(), + )); + c + }; + + token_transfer_ctx + .burn_coins_execute(&IBC_ADDRESS, &coin, &String::new().into()) + .map_err(Error::TokenTransfer) + } + } + + fn write_ack_and_events( + &mut self, + packet: &Packet, + acknowledgement: &Acknowledgement, + ) -> Result<(), Self::Error> { + tracing::debug!(?packet, ?acknowledgement, "PFM write_ack_and_events"); + let mut ctx = IbcContext::::new( + self.transfer_module.ctx.inner.clone(), + ); + commit_packet_acknowledgment(&mut ctx, packet, acknowledgement) + .map_err(|e| Error::Context(Box::new(e)))?; + emit_packet_acknowledgement_event( + &mut ctx, + packet.clone(), + acknowledgement.clone(), + ) + .map_err(|e| Error::Context(Box::new(e))) + } + + fn override_receiver( + &self, + _channel: &ChannelId, + _original_sender: &Signer, + ) -> Result { + Ok(IBC_ADDRESS.to_string().into()) + } + + #[allow(clippy::arithmetic_side_effects)] + fn timeout_timestamp( + &self, + timeout_duration: dur::Duration, + ) -> Result { + let timestamp = self + .transfer_module + .ctx + .inner + .borrow() + .host_timestamp() + .map_err(|e| Error::Other(e.to_string()))? + + timeout_duration.try_to_std().ok_or_else(|| { + Error::Other(format!( + "Packet timeout duration is too large: {timeout_duration}" + )) + })?; + let ts = timestamp + .map(TimeoutTimestamp::At) + .map_err(|e| Error::Other(e.to_string()))?; + tracing::debug!(timeout_timestamp = ?ts, "PFM timeout_timestamp"); + Ok(ts) + } + + fn store_inflight_packet( + &mut self, + key: InFlightPacketKey, + inflight_packet: InFlightPacket, + ) -> Result<(), Self::Error> { + tracing::debug!(?key, ?inflight_packet, "PFM store_inflight_packet"); + let mut ctx = self.transfer_module.ctx.inner.borrow_mut(); + let key = get_inflight_packet_key(&key); + ctx.storage_mut() + .write(&key, inflight_packet) + .map_err(Error::Storage) + } + + fn retrieve_inflight_packet( + &self, + key: &InFlightPacketKey, + ) -> Result, Self::Error> { + let mut ctx = self.transfer_module.ctx.inner.borrow_mut(); + let key = get_inflight_packet_key(key); + let packet = ctx.storage_mut().read(&key).map_err(Error::Storage); + + tracing::debug!(?key, ?packet, "PFM retrieve_inflight_packet"); + + packet + } + + fn delete_inflight_packet( + &mut self, + key: &InFlightPacketKey, + ) -> Result<(), Self::Error> { + tracing::debug!(?key, "PFM delete_inflight_packet"); + let mut ctx = self.transfer_module.ctx.inner.borrow_mut(); + let key = get_inflight_packet_key(key); + ctx.storage_mut().delete(&key).map_err(Error::Storage) + } +} + +impl ModuleWrapper for PacketForwardMiddleware +where + T: Module + PfmContext, +{ + fn as_module(&self) -> &dyn Module { + self + } + + fn as_module_mut(&mut self) -> &mut dyn Module { + self + } + + fn module_id(&self) -> ModuleId { + ModuleId::new(ibc::apps::transfer::types::MODULE_ID_STR.to_string()) + } + + fn port_id(&self) -> PortId { + PortId::transfer() + } +} diff --git a/crates/ibc/src/context/token_transfer.rs b/crates/ibc/src/context/token_transfer.rs index da3bedc41c..fecc8d4d2d 100644 --- a/crates/ibc/src/context/token_transfer.rs +++ b/crates/ibc/src/context/token_transfer.rs @@ -25,8 +25,8 @@ pub struct TokenTransferContext where C: IbcCommonContext, { - inner: Rc>, - verifiers: Rc>>, + pub(crate) inner: Rc>, + pub(crate) verifiers: Rc>>, is_shielded: bool, } @@ -47,7 +47,7 @@ where } /// Insert a verifier address whose VP will verify the tx. - fn insert_verifier(&mut self, addr: &Address) { + pub(crate) fn insert_verifier(&mut self, addr: &Address) { self.verifiers.borrow_mut().insert(addr.clone()); } diff --git a/crates/ibc/src/context/transfer_mod.rs b/crates/ibc/src/context/transfer_mod.rs index 9a1075e280..a30826514d 100644 --- a/crates/ibc/src/context/transfer_mod.rs +++ b/crates/ibc/src/context/transfer_mod.rs @@ -276,7 +276,7 @@ where &mut self, packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { on_recv_packet_execute(&mut self.ctx, packet) } @@ -497,10 +497,10 @@ pub mod testing { &mut self, _packet: &Packet, _relayer: &Signer, - ) -> (ModuleExtras, Acknowledgement) { + ) -> (ModuleExtras, Option) { ( ModuleExtras::empty(), - AcknowledgementStatus::success(ack_success_b64()).into(), + Some(AcknowledgementStatus::success(ack_success_b64()).into()), ) } diff --git a/crates/ibc/src/context/validation.rs b/crates/ibc/src/context/validation.rs index 0f00feefcf..7173a14a82 100644 --- a/crates/ibc/src/context/validation.rs +++ b/crates/ibc/src/context/validation.rs @@ -5,6 +5,7 @@ use ibc::core::channel::types::channel::ChannelEnd; use ibc::core::channel::types::commitment::{ AcknowledgementCommitment, PacketCommitment, }; +use ibc::core::channel::types::error::PacketError; use ibc::core::channel::types::packet::Receipt; use ibc::core::client::context::{ ClientValidationContext, ExtClientValidationContext, @@ -253,11 +254,18 @@ where &self, path: &AckPath, ) -> Result { - self.inner.borrow().packet_ack( + let maybe_ack = self.inner.borrow().packet_ack( &path.port_id, &path.channel_id, path.sequence, - ) + )?; + + maybe_ack.ok_or_else(|| { + PacketError::PacketAcknowledgementNotFound { + sequence: path.sequence, + } + .into() + }) } fn channel_counter(&self) -> Result { diff --git a/crates/ibc/src/lib.rs b/crates/ibc/src/lib.rs index 74830fda51..d40ee18d61 100644 --- a/crates/ibc/src/lib.rs +++ b/crates/ibc/src/lib.rs @@ -143,6 +143,8 @@ pub enum Error { ChainId(IdentifierError), #[error("Verifier insertion error: {0}")] Verifier(StorageError), + #[error("Storage read/write error: {0}")] + Storage(StorageError), #[error("IBC error: {0}")] Other(String), } @@ -690,7 +692,9 @@ where // Extract MASP tx from the memo in the packet if needed let masp_tx = match &*envelope { MsgEnvelope::Packet(PacketMsg::Recv(msg)) - if self.is_receiving_success(msg)? => + if self + .is_receiving_success(msg)? + .is_some_and(|ack_succ| ack_succ) => { extract_masp_tx_from_packet(&msg.packet) } @@ -713,8 +717,8 @@ where pub fn is_receiving_success( &self, msg: &IbcMsgRecvPacket, - ) -> Result { - let packet_ack = self + ) -> Result, Error> { + let Some(packet_ack) = self .ctx .inner .borrow() @@ -723,11 +727,14 @@ where &msg.packet.chan_id_on_b, msg.packet.seq_on_a, ) - .map_err(|e| Error::Context(Box::new(e)))?; + .map_err(|e| Error::Context(Box::new(e)))? + else { + return Ok(None); + }; let success_ack_commitment = compute_ack_commitment( &AcknowledgementStatus::success(ack_success_b64()).into(), ); - Ok(packet_ack == success_ack_commitment) + Ok(Some(packet_ack == success_ack_commitment)) } /// Validate according to the message in IBC VP diff --git a/crates/ibc/src/vp/mod.rs b/crates/ibc/src/vp/mod.rs index 6df0eba624..4ecd134963 100644 --- a/crates/ibc/src/vp/mod.rs +++ b/crates/ibc/src/vp/mod.rs @@ -27,6 +27,7 @@ use namada_vp::native_vp::{Ctx, CtxPreStorageRead, NativeVp, VpEvaluator}; use namada_vp::VpEnv; use thiserror::Error; +use crate::context::pfm_mod::PfmTransferModule; use crate::core::host::types::identifiers::ChainId as IbcChainId; use crate::core::host::types::path::UPGRADED_IBC_STATE; use crate::event::IbcEvent; @@ -36,8 +37,8 @@ use crate::storage::{ }; use crate::trace::calc_hash; use crate::{ - Error as ActionError, IbcActions, NftTransferModule, TransferModule, - ValidationParams, COMMITMENT_PREFIX, + Error as ActionError, IbcActions, NftTransferModule, ValidationParams, + COMMITMENT_PREFIX, }; #[allow(missing_docs)] @@ -246,7 +247,8 @@ where ctx.clone(), verifiers.clone(), ); - let module = TransferModule::new(ctx.clone(), verifiers); + let module = + PfmTransferModule::<_, ParamsPseudo>::wrap(ctx.clone(), verifiers); actions.add_transfer_module(module); let module = NftTransferModule::<_, Token>::new(ctx.clone()); actions.add_transfer_module(module); @@ -301,7 +303,8 @@ where IbcActions::<_, Params, Token>::new(ctx.clone(), verifiers.clone()); actions.set_validation_params(self.validation_params()?); - let module = TransferModule::new(ctx.clone(), verifiers); + let module = + PfmTransferModule::<_, Params>::wrap(ctx.clone(), verifiers); actions.add_transfer_module(module); let module = NftTransferModule::<_, Token>::new(ctx); actions.add_transfer_module(module); diff --git a/crates/tests/Cargo.toml b/crates/tests/Cargo.toml index 14e422cce2..e4d029ac7f 100644 --- a/crates/tests/Cargo.toml +++ b/crates/tests/Cargo.toml @@ -38,7 +38,9 @@ namada_vm = {path = "../vm", features = ["testing"]} concat-idents.workspace = true derivative.workspace = true +dur.workspace = true hyper = {version = "0.14.20", features = ["full"]} +ibc-middleware-packet-forward.workspace = true ibc-testkit.workspace = true ics23.workspace = true itertools.workspace = true diff --git a/crates/tests/src/e2e/helpers.rs b/crates/tests/src/e2e/helpers.rs index ab3579a1a2..523b631ee5 100644 --- a/crates/tests/src/e2e/helpers.rs +++ b/crates/tests/src/e2e/helpers.rs @@ -31,7 +31,7 @@ use toml::Value; use super::setup::{ self, ensure_hot_key, run_cosmos_cmd, sleep, NamadaBgCmd, NamadaCmd, Test, - ENV_VAR_DEBUG, ENV_VAR_USE_PREBUILT_BINARIES, + TestDir, ENV_VAR_DEBUG, ENV_VAR_USE_PREBUILT_BINARIES, }; use crate::e2e::setup::{Bin, CosmosChainType, Who, APPS_PACKAGE}; use crate::strings::{LEDGER_STARTED, TX_APPLIED_SUCCESS}; @@ -464,7 +464,11 @@ pub fn epochs_per_year_from_min_duration(min_duration: u64) -> u64 { } /// Make a Hermes config -pub fn make_hermes_config(test_a: &Test, test_b: &Test) -> Result<()> { +pub fn make_hermes_config( + hermes_dir: &TestDir, + test_a: &Test, + test_b: &Test, +) -> Result<()> { let mut config = toml::map::Map::new(); let mut global = toml::map::Map::new(); @@ -502,28 +506,19 @@ pub fn make_hermes_config(test_a: &Test, test_b: &Test) -> Result<()> { config.insert("telemetry".to_owned(), Value::Table(telemetry)); let chains = vec![ - make_hermes_chain_config(test_a), + make_hermes_chain_config(hermes_dir, test_a), match CosmosChainType::chain_type(test_b.net.chain_id.as_str()) { - Ok(chain_type) => { - make_hermes_chain_config_for_cosmos(chain_type, test_b) - } - Err(_) => make_hermes_chain_config(test_b), + Ok(chain_type) => make_hermes_chain_config_for_cosmos( + hermes_dir, chain_type, test_b, + ), + Err(_) => make_hermes_chain_config(hermes_dir, test_b), }, ]; config.insert("chains".to_owned(), Value::Array(chains)); let toml_string = toml::to_string(&Value::Table(config)).unwrap(); - let hermes_dir = test_a.test_dir.as_ref().join("hermes"); - std::fs::create_dir_all(&hermes_dir).unwrap(); - let config_path = hermes_dir.join("config.toml"); - let mut file = File::create(config_path).unwrap(); - file.write_all(toml_string.as_bytes()).map_err(|e| { - eyre!(format!("Writing a Hermes config failed: {}", e,)) - })?; - // One Hermes config.toml is OK, but add one more config.toml to execute - // Hermes from test_b - let hermes_dir = test_b.test_dir.as_ref().join("hermes"); + let hermes_dir = hermes_dir.as_ref().join("hermes"); std::fs::create_dir_all(&hermes_dir).unwrap(); let config_path = hermes_dir.join("config.toml"); let mut file = File::create(config_path).unwrap(); @@ -534,7 +529,7 @@ pub fn make_hermes_config(test_a: &Test, test_b: &Test) -> Result<()> { Ok(()) } -fn make_hermes_chain_config(test: &Test) -> Value { +fn make_hermes_chain_config(_hermes_dir: &TestDir, test: &Test) -> Value { let chain_id = test.net.chain_id.as_str(); let rpc_addr = get_actor_rpc(test, Who::Validator(0)); let rpc_addr = rpc_addr.strip_prefix("http://").unwrap(); @@ -580,12 +575,14 @@ fn make_hermes_chain_config(test: &Test) -> Value { } fn make_hermes_chain_config_for_cosmos( + hermes_dir: &TestDir, chain_type: CosmosChainType, test: &Test, ) -> Value { let mut table = toml::map::Map::new(); table.insert("mode".to_owned(), Value::String("push".to_owned())); - let url = format!("ws://{}/websocket", setup::constants::COSMOS_RPC); + let offset = chain_type.get_offset(); + let url = format!("ws://127.0.0.1:6416{}/websocket", offset); table.insert("url".to_owned(), Value::String(url)); table.insert("batch_delay".to_owned(), Value::String("500ms".to_owned())); let event_source = Value::Table(table); @@ -596,14 +593,16 @@ fn make_hermes_chain_config_for_cosmos( Value::String(test.net.chain_id.to_string()), ); chain.insert("type".to_owned(), Value::String("CosmosSdk".to_owned())); + chain.insert( "rpc_addr".to_owned(), - Value::String(format!("http://{}", setup::constants::COSMOS_RPC)), + Value::String(format!("http://127.0.0.1:6416{}", offset)), ); chain.insert( "grpc_addr".to_owned(), - Value::String("http://127.0.0.1:9090".to_owned()), + Value::String(format!("http://127.0.0.1:{}", offset + 9090)), ); + chain.insert("event_source".to_owned(), event_source); chain.insert( "account_prefix".to_owned(), @@ -613,7 +612,8 @@ fn make_hermes_chain_config_for_cosmos( "key_name".to_owned(), Value::String(setup::constants::COSMOS_RELAYER.to_string()), ); - let key_dir = test.test_dir.as_ref().join("hermes/keys"); + let hermes_dir: &Path = hermes_dir.as_ref(); + let key_dir = hermes_dir.join("hermes/keys"); chain.insert( "key_store_folder".to_owned(), Value::String(key_dir.to_string_lossy().to_string()), @@ -645,6 +645,28 @@ pub fn update_cosmos_config(test: &Test) -> Result<()> { *timeout_propose = "1s".into(); } } + let offset = CosmosChainType::chain_type(test.net.chain_id.as_str()) + .unwrap() + .get_offset(); + let p2p = values + .get_mut("p2p") + .expect("Test failed") + .as_table_mut() + .expect("Test failed"); + let Some(laddr) = p2p.get_mut("laddr") else { + panic!("Test failed") + }; + *laddr = format!("tcp://0.0.0.0:266{}{}", offset, offset).into(); + let rpc = values + .get_mut("rpc") + .expect("Test failed") + .as_table_mut() + .expect("Test failed"); + let Some(laddr) = rpc.get_mut("laddr") else { + panic!("Test failed") + }; + *laddr = format!("tcp://0.0.0.0:6416{offset}").into(); + let mut file = OpenOptions::new() .write(true) .truncate(true) @@ -711,6 +733,13 @@ pub fn update_cosmos_config(test: &Test) -> Result<()> { Ok(()) } +pub fn get_cosmos_rpc_address(test: &Test) -> String { + let offset = CosmosChainType::chain_type(test.net.chain_id.as_str()) + .unwrap() + .get_offset(); + format!("127.0.0.1:6416{offset}") +} + pub fn find_cosmos_address( test: &Test, alias: impl AsRef, @@ -732,7 +761,8 @@ pub fn find_cosmos_address( } pub fn get_cosmos_gov_address(test: &Test) -> Result { - let args = ["query", "auth", "module-account", "gov"]; + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); + let args = ["query", "auth", "module-account", "gov", "--node", &rpc]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; let (_, matched) = cosmos.exp_regex("cosmos[a-z0-9]+")?; diff --git a/crates/tests/src/e2e/ibc_tests.rs b/crates/tests/src/e2e/ibc_tests.rs index bde2ca2fa3..5e42168925 100644 --- a/crates/tests/src/e2e/ibc_tests.rs +++ b/crates/tests/src/e2e/ibc_tests.rs @@ -15,6 +15,8 @@ use std::path::{Path, PathBuf}; use color_eyre::eyre::Result; use eyre::eyre; +use ibc_middleware_packet_forward::ForwardMetadata; +use itertools::Either; use namada_apps_lib::client::rpc::query_storage_value_bytes; use namada_apps_lib::config::ethereum_bridge; use namada_apps_lib::config::genesis::templates; @@ -47,7 +49,8 @@ use sha2::{Digest, Sha256}; use crate::e2e::helpers::{ epoch_sleep, epochs_per_year_from_min_duration, find_address, - find_cosmos_address, get_actor_rpc, get_cosmos_gov_address, get_epoch, + find_cosmos_address, get_actor_rpc, get_cosmos_gov_address, + get_cosmos_rpc_address, get_epoch, }; use crate::e2e::ledger_tests::{ start_namada_ledger_node_wait_wasm, write_json_file, @@ -55,8 +58,10 @@ use crate::e2e::ledger_tests::{ use crate::e2e::setup::{ self, apply_use_device, run_cosmos_cmd, run_hermes_cmd, set_ethereum_bridge_mode, setup_cosmos, setup_hermes, sleep, working_dir, - Bin, CosmosChainType, NamadaCmd, Test, Who, ENV_VAR_COSMWASM_CONTRACT_DIR, + Bin, CosmosChainType, NamadaCmd, Test, TestDir, Who, + ENV_VAR_COSMWASM_CONTRACT_DIR, }; +use crate::ibc::primitives::Signer; use crate::strings::TX_APPLIED_SUCCESS; use crate::{run, run_as}; @@ -100,14 +105,15 @@ fn ibc_transfers() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_namada = FT_PORT_ID.parse().unwrap(); let port_id_gaia = FT_PORT_ID.parse().unwrap(); let (channel_id_namada, channel_id_gaia) = create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, @@ -115,7 +121,7 @@ fn ibc_transfers() -> Result<()> { )?; // Start relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let bg_hermes = hermes.background(); // 1. Transparent transfers @@ -135,7 +141,12 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; check_balance(&test, ALBERT, APFEL, 999_998)?; let token_addr = find_address(&test, APFEL)?; @@ -161,7 +172,7 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // Check the balances check_balance(&test, ALBERT, APFEL, 999_999)?; @@ -184,7 +195,7 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // Check the token on Namada let ibc_denom_on_namada = @@ -206,7 +217,12 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // Check the balances check_balance(&test, ALBERT, &ibc_denom_on_namada, 100)?; @@ -239,10 +255,15 @@ fn ibc_transfers() -> Result<()> { 100, &port_id_gaia, &channel_id_gaia, - Some(shielding_data_path), + Some(Either::Left(shielding_data_path)), None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test_gaia)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_gaia, + &channel_id_gaia, + &test_gaia, + )?; // Check the token on Namada check_balance(&test, AA_VIEWING_KEY, &ibc_denom_on_namada, 100)?; check_cosmos_balance(&test_gaia, COSMOS_USER, COSMOS_COIN, 800)?; @@ -275,7 +296,12 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; check_balance(&test, AB_VIEWING_KEY, &ibc_denom_on_namada, 40)?; check_cosmos_balance(&test_gaia, COSMOS_USER, COSMOS_COIN, 810)?; @@ -297,10 +323,10 @@ fn ibc_transfers() -> Result<()> { 1_000_000, &port_id_gaia, &channel_id_gaia, - Some(memo_path), + Some(Either::Left(memo_path)), None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // Check the token on Namada check_balance(&test, AA_VIEWING_KEY, APFEL, 1)?; @@ -321,7 +347,12 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // The balance should not be changed check_balance(&test, ALBERT, APFEL, 999_999)?; @@ -347,10 +378,15 @@ fn ibc_transfers() -> Result<()> { sleep(10); // Restart relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let bg_hermes = hermes.background(); - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // The balance should not be changed check_balance(&test, ALBERT, &ibc_denom_on_namada, 100)?; @@ -369,7 +405,12 @@ fn ibc_transfers() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // Check the token has been refunded to the refund target check_balance(&test, AA_VIEWING_KEY, &ibc_denom_on_namada, 40)?; check_balance(&test, IBC_REFUND_TARGET_ALIAS, &ibc_denom_on_namada, 10)?; @@ -397,10 +438,15 @@ fn ibc_transfers() -> Result<()> { sleep(10); // Restart relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let _bg_hermes = hermes.background(); - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // Check the token has been refunded to the refund target check_balance(&test, AA_VIEWING_KEY, APFEL, 0)?; check_balance(&test, IBC_REFUND_TARGET_ALIAS, APFEL, 1)?; @@ -424,7 +470,12 @@ fn ibc_transfers() -> Result<()> { // MASP VP shall reject it, make it timeout Some(Duration::new(10, 0)), )?; - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // Check the balance didn't change check_balance(&test, AA_VIEWING_KEY, &ibc_denom_on_namada, 40)?; check_cosmos_balance(&test_gaia, COSMOS_USER, COSMOS_COIN, 810)?; @@ -446,11 +497,16 @@ fn ibc_transfers() -> Result<()> { 101, &port_id_gaia, &channel_id_gaia, - Some(shielding_data_path), + Some(Either::Left(shielding_data_path)), // MASP VP shall reject it, make it timeout Some(Duration::new(10, 0)), )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test_gaia)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_gaia, + &channel_id_gaia, + &test_gaia, + )?; // Check the balances didn't change check_balance(&test, AA_VIEWING_KEY, &ibc_denom_on_namada, 40)?; check_cosmos_balance(&test_gaia, COSMOS_USER, COSMOS_COIN, 810)?; @@ -477,7 +533,7 @@ fn ibc_nft_transfers() -> Result<()> { let _bg_ledger = ledger.background(); let _bg_wasmd = cosmwasm.background(); - setup_hermes(&test, &test_cosmwasm)?; + let hermes_dir = setup_hermes(&test, &test_cosmwasm)?; let port_id_namada: PortId = NFT_PORT_ID.parse().unwrap(); let (cw721_contract, ics721_contract) = @@ -488,6 +544,7 @@ fn ibc_nft_transfers() -> Result<()> { let port_id_cosmwasm = get_cosmwasm_port_id(&test_cosmwasm, &ics721_contract)?; let (channel_id_namada, channel_id_cosmwasm) = create_channel_with_hermes( + &hermes_dir, &test, &test_cosmwasm, &port_id_namada, @@ -512,7 +569,12 @@ fn ibc_nft_transfers() -> Result<()> { None, None, )?; - clear_packet(&port_id_cosmwasm, &channel_id_cosmwasm, &test_cosmwasm)?; + clear_packet( + &hermes_dir, + &port_id_cosmwasm, + &channel_id_cosmwasm, + &test_cosmwasm, + )?; check_balance(&test, &namada_receiver, &ibc_trace_on_namada, 1)?; // Namada to CosmWasm @@ -529,7 +591,7 @@ fn ibc_nft_transfers() -> Result<()> { None, None, )?; - clear_packet(&port_id_namada, &channel_id_namada, &test)?; + clear_packet(&hermes_dir, &port_id_namada, &channel_id_namada, &test)?; check_balance(&test, &namada_receiver, &ibc_trace_on_namada, 0)?; // 2. Shielding/Unshielding transfers @@ -553,7 +615,12 @@ fn ibc_nft_transfers() -> Result<()> { Some(shielding_data_path), None, )?; - clear_packet(&port_id_cosmwasm, &channel_id_cosmwasm, &test_cosmwasm)?; + clear_packet( + &hermes_dir, + &port_id_cosmwasm, + &channel_id_cosmwasm, + &test_cosmwasm, + )?; check_balance(&test, AA_VIEWING_KEY, &ibc_trace_on_namada, 1)?; // Shielded transfer on Namada @@ -584,7 +651,7 @@ fn ibc_nft_transfers() -> Result<()> { None, None, )?; - clear_packet(&port_id_namada, &channel_id_namada, &test)?; + clear_packet(&hermes_dir, &port_id_namada, &channel_id_namada, &test)?; check_balance(&test, AB_VIEWING_KEY, &ibc_trace_on_namada, 0)?; Ok(()) @@ -607,14 +674,15 @@ fn pgf_over_ibc() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_namada = FT_PORT_ID.parse().unwrap(); let port_id_gaia: PortId = FT_PORT_ID.parse().unwrap(); let (channel_id_namada, channel_id_gaia) = create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, @@ -622,7 +690,7 @@ fn pgf_over_ibc() -> Result<()> { )?; // Start relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let _bg_hermes = hermes.background(); // Transfer to PGF account @@ -668,7 +736,12 @@ fn pgf_over_ibc() -> Result<()> { while epoch < grace_epoch { epoch = epoch_sleep(&test, &rpc, 120)?; } - wait_for_packet_relay(&port_id_namada, &channel_id_namada, &test)?; + wait_for_packet_relay( + &hermes_dir, + &port_id_namada, + &channel_id_namada, + &test, + )?; // Check balances after funding over IBC let token_addr = find_address(&test, NAM)?; @@ -704,7 +777,7 @@ fn fee_payment_with_ibc_token() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); @@ -727,10 +800,11 @@ fn fee_payment_with_ibc_token() -> Result<()> { submit_votes(&test)?; // Create an IBC channel while waiting the grace epoch - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_gaia = FT_PORT_ID.parse().unwrap(); let port_id_namada = FT_PORT_ID.parse().unwrap(); let (channel_id_namada, channel_id_gaia) = create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, @@ -739,7 +813,7 @@ fn fee_payment_with_ibc_token() -> Result<()> { let ibc_token_on_namada = format!("{port_id_namada}/{channel_id_namada}/{COSMOS_COIN}"); // Start relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let _bg_hermes = hermes.background(); // wait for the grace @@ -761,7 +835,7 @@ fn fee_payment_with_ibc_token() -> Result<()> { None, None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // Check the token on Namada check_balance(&test, ALBERT_KEY, &ibc_token_on_namada, 250)?; @@ -810,7 +884,7 @@ fn ibc_token_inflation() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); @@ -833,17 +907,18 @@ fn ibc_token_inflation() -> Result<()> { submit_votes(&test)?; // Create an IBC channel while waiting the grace epoch - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_namada = FT_PORT_ID.parse().unwrap(); let port_id_gaia = FT_PORT_ID.parse().unwrap(); let (channel_id_namada, channel_id_gaia) = create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, &port_id_gaia, )?; // Start relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let _bg_hermes = hermes.background(); // wait for the grace @@ -871,10 +946,10 @@ fn ibc_token_inflation() -> Result<()> { 1, &port_id_gaia, &channel_id_gaia, - Some(shielding_data_path), + Some(Either::Left(shielding_data_path)), None, )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // wait the next masp epoch to dispense the reward let mut epoch = get_epoch(&test, &rpc).unwrap(); @@ -900,14 +975,16 @@ fn ibc_upgrade_client() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); + sleep(5); - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_namada = FT_PORT_ID.parse().unwrap(); let port_id_gaia: PortId = FT_PORT_ID.parse().unwrap(); create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, @@ -932,7 +1009,7 @@ fn ibc_upgrade_client() -> Result<()> { } // Upgrade the IBC client of Gaia on Namada with Hermes - upgrade_client(&test, test.net.chain_id.to_string(), upgrade_height)?; + upgrade_client(&hermes_dir, test.net.chain_id.to_string(), upgrade_height)?; // Check the upgraded client let upgraded_client_state = @@ -971,14 +1048,15 @@ fn ibc_rate_limit() -> Result<()> { setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) }; let (ledger, gaia, test, test_gaia) = - run_namada_cosmos(CosmosChainType::Gaia, update_genesis)?; + run_namada_cosmos(CosmosChainType::Gaia(None), update_genesis)?; let _bg_ledger = ledger.background(); let _bg_gaia = gaia.background(); - setup_hermes(&test, &test_gaia)?; + let hermes_dir = setup_hermes(&test, &test_gaia)?; let port_id_namada = FT_PORT_ID.parse().unwrap(); let port_id_gaia: PortId = FT_PORT_ID.parse().unwrap(); let (channel_id_namada, channel_id_gaia) = create_channel_with_hermes( + &hermes_dir, &test, &test_gaia, &port_id_namada, @@ -986,7 +1064,7 @@ fn ibc_rate_limit() -> Result<()> { )?; // Start relaying - let hermes = run_hermes(&test)?; + let hermes = run_hermes(&hermes_dir)?; let _bg_hermes = hermes.background(); // wait for the next epoch @@ -1075,7 +1153,7 @@ fn ibc_rate_limit() -> Result<()> { None, Some(Duration::new(10, 0)), )?; - wait_for_packet_relay(&port_id_gaia, &channel_id_gaia, &test)?; + wait_for_packet_relay(&hermes_dir, &port_id_gaia, &channel_id_gaia, &test)?; // Check if Namada hasn't receive it let ibc_denom = @@ -1088,6 +1166,717 @@ fn ibc_rate_limit() -> Result<()> { Ok(()) } +/// Test the happy flows of ibc pfm +/// +/// Setup: Two instances of Gaia and one +/// Namada instance. +/// +/// 1. Test sending a transfer from first cosmos chain to the second via the PFM +/// module on Namada (henceforth denoted "via PFM") +/// 2. Test sending the above transfer back to first cosmos chain via PFM +/// 3. Send wrapped NAM from first cosmos chain to the second via PFM +/// 4. Reverse the transaction in the step above +#[test] +fn ibc_pfm_happy_flows() -> Result<()> { + let update_genesis = + |mut genesis: templates::All, base_dir: &_| { + genesis.parameters.parameters.epochs_per_year = + epochs_per_year_from_min_duration(1800); + genesis.parameters.ibc_params.default_mint_limit = + Amount::max_signed(); + genesis + .parameters + .ibc_params + .default_per_epoch_throughput_limit = Amount::max_signed(); + setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) + }; + let (ledger, gaia_1, test, test_gaia_1) = + run_namada_cosmos(CosmosChainType::Gaia(Some(1)), update_genesis)?; + + // set up a second cosmos network + let test_gaia_2 = setup_cosmos(CosmosChainType::Gaia(Some(2)))?; + let gaia_2 = run_cosmos(&test_gaia_2, false)?; + sleep(5); + + let _bg_ledger = ledger.background(); + let _bg_gaia_1 = gaia_1.background(); + let _bg_gaia_2 = gaia_2.background(); + let hermes_gaia1_namada = setup_hermes(&test, &test_gaia_1)?; + let hermes_namada_gaia2 = setup_hermes(&test, &test_gaia_2)?; + sleep(5); + // create hermes relayers for connections between both cosmos chains and + // namada + let port_id_namada = FT_PORT_ID.parse().unwrap(); + let port_id_gaia_1 = FT_PORT_ID.parse().unwrap(); + let port_id_gaia_2 = FT_PORT_ID.parse().unwrap(); + + let (channel_id_gaia_1, channel_id_namada_1) = create_channel_with_hermes( + &hermes_gaia1_namada, + &test_gaia_1, + &test, + &port_id_namada, + &port_id_gaia_1, + )?; + let (channel_id_gaia_2, channel_id_namada_2) = create_channel_with_hermes( + &hermes_namada_gaia2, + &test_gaia_2, + &test, + &port_id_namada, + &port_id_gaia_2, + )?; + + // Start relaying + let hermes_1 = run_hermes(&hermes_gaia1_namada)?; + let hermes_2 = run_hermes(&hermes_namada_gaia2)?; + let _bg_hermes_1 = hermes_1.background(); + let _bg_hermes_2 = hermes_2.background(); + + // ------------------- Step 1. ------------------- + + // Bertha is our most trusted intermediary in all things + let namada_receiver = find_address(&test, BERTHA)?.to_string(); + // this will cause the ibc packet to be forwarded to the second + // cosmos chain. + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_2, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_2, + None, + ); + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + "samoleans", + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + // Check the samoleans have been received on the second cosmos chain + check_cosmos_balance( + &test_gaia_2, + COSMOS_USER, + format!( + "transfer/{channel_id_gaia_2}/transfer/{channel_id_namada_1}/\ + samoleans" + ), + 10, + )?; + + // Check the samoleans have been sent from the first cosmos chain + check_cosmos_balance(&test_gaia_1, COSMOS_USER, "samoleans", 1000 - 10)?; + + // ------------------- Step 2. ------------------- + + // this will cause the ibc packet to be forwarded to the first + // cosmos chain. + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_1, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_1, + None, + ); + transfer_from_cosmos( + &test_gaia_2, + COSMOS_USER, + &namada_receiver, + format!( + "transfer/{channel_id_gaia_2}/transfer/{channel_id_namada_1}/\ + samoleans" + ), + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_namada, + &channel_id_namada_2, + &test, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_gaia_1, + &channel_id_gaia_1, + &test_gaia_1, + )?; + + // Check the samoleans have been received on the fist cosmos chain + check_cosmos_balance(&test_gaia_1, COSMOS_USER, "samoleans", 1000)?; + + // ------------------- Step 3. ------------------- + let nam_addr = find_address(&test, NAM)?; + // we first send some NAM to the first cosmos chain. + let gaia_receiver = find_cosmos_address(&test_gaia_1, COSMOS_USER)?; + transfer( + &test, + BERTHA, + gaia_receiver, + NAM, + 20, + Some(BERTHA_KEY), + &port_id_namada, + &channel_id_namada_1, + None, + None, + None, + )?; + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_gaia_1, + &channel_id_gaia_1, + &test_gaia_1, + )?; + + // Check the NAM have been sent to the first cosmos chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000, + )?; + + // this will cause the ibc packet to be forwarded to the second + // cosmos chain. + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_2, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_2, + None, + ); + + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 10_000_000, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + // Check the NAM have been received on the second cosmos chain + check_cosmos_balance( + &test_gaia_2, + COSMOS_USER, + format!("transfer/{channel_id_gaia_2}/{nam_addr}"), + 10_000_000, + )?; + + // Check the NAM have been sent from the first cosmos chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000 - 10_000_000, + )?; + + // ------------------- Step 4. ------------------- + + // this will cause the ibc packet to be forwarded to the first + // cosmos chain. + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_1, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_1, + None, + ); + transfer_from_cosmos( + &test_gaia_2, + COSMOS_USER, + &namada_receiver, + format!("transfer/{channel_id_gaia_2}/{nam_addr}"), + 10_000_000, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_namada, + &channel_id_namada_2, + &test, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_gaia_1, + &channel_id_gaia_1, + &test_gaia_1, + )?; + + // Check the NAM have been received on the first cosmos chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000, + )?; + + Ok(()) +} +/// Test the flows of ibc pfm where the packet cannot be +/// completed and refunds must be issued. +/// +/// Setup: Two instances of Gaia and one +/// Namada instance. +/// +/// 1. Test sending a transfer from first cosmos chain to the second via the PFM +/// module on Namada (henceforth denoted "via PFM"), failing on the second +/// cosmos chain due to an error. +/// 2. Same as above except that the failure occurs due to a time-out on the +/// second cosmos chain. +/// 3. Same as the first except that wrapped NAM is sent from the first cosmos +/// chain +/// 4. Same as above except that the failure occurs due to a time-out on the +/// second cosmos chain. +/// 5. Test sending assets from the second cosmos network to the first and then +/// failing to send it back to the second due to an error +/// 6. Same as above except that the failure occurs due to a time-out on the +/// second cosmos chain. +#[test] +fn ibc_pfm_unhappy_flows() -> Result<()> { + let update_genesis = + |mut genesis: templates::All, base_dir: &_| { + genesis.parameters.parameters.epochs_per_year = + epochs_per_year_from_min_duration(1800); + genesis.parameters.ibc_params.default_mint_limit = + Amount::max_signed(); + genesis + .parameters + .ibc_params + .default_per_epoch_throughput_limit = Amount::max_signed(); + setup::set_validators(1, genesis, base_dir, |_| 0, vec![]) + }; + let (ledger, gaia_1, test, test_gaia_1) = + run_namada_cosmos(CosmosChainType::Gaia(Some(1)), update_genesis)?; + + // set up a second cosmos network + let test_gaia_2 = setup_cosmos(CosmosChainType::Gaia(Some(2)))?; + let gaia_2 = run_cosmos(&test_gaia_2, false)?; + sleep(5); + + let _bg_ledger = ledger.background(); + let _bg_gaia_1 = gaia_1.background(); + let _bg_gaia_2 = gaia_2.background(); + let hermes_gaia1_namada = setup_hermes(&test, &test_gaia_1)?; + let hermes_namada_gaia2 = setup_hermes(&test, &test_gaia_2)?; + sleep(5); + // create hermes relayers for connections between both cosmos chains and + // namada + let port_id_namada = FT_PORT_ID.parse().unwrap(); + let port_id_gaia_1 = FT_PORT_ID.parse().unwrap(); + let port_id_gaia_2 = FT_PORT_ID.parse().unwrap(); + + let (channel_id_gaia_1, channel_id_namada_1) = create_channel_with_hermes( + &hermes_gaia1_namada, + &test_gaia_1, + &test, + &port_id_namada, + &port_id_gaia_1, + )?; + let (channel_id_gaia_2, channel_id_namada_2) = create_channel_with_hermes( + &hermes_namada_gaia2, + &test_gaia_2, + &test, + &port_id_namada, + &port_id_gaia_2, + )?; + + // Start relaying + let hermes_1 = run_hermes(&hermes_gaia1_namada)?; + let hermes_2 = run_hermes(&hermes_namada_gaia2)?; + let _bg_hermes_1 = hermes_1.background(); + let bg_hermes_2 = hermes_2.background(); + + // ------------------- Step 1. ------------------- + + // Bertha is our most trusted intermediary in all things + let namada_receiver = find_address(&test, BERTHA)?.to_string(); + // this will cause the ibc packet to be forwarded to the second + // cosmos chain. + let pfm_memo = packet_forward_memo( + "Hodor".to_string().into(), + &port_id_namada, + &channel_id_namada_2, + None, + ); + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + "samoleans", + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the samoleans have been refunded on the first chain + check_cosmos_balance(&test_gaia_1, COSMOS_USER, "samoleans", 1000)?; + + // ------------------- Step 2. ------------------- + + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_1, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_2, + Some(Duration::new(1, 0)), + ); + // Stop Hermes for timeout test + let mut hermes_2 = bg_hermes_2.foreground(); + hermes_2.interrupt()?; + + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + "samoleans", + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + + // wait for the timeout + sleep(10); + + // Restart relaying + let hermes_2 = run_hermes(&hermes_namada_gaia2)?; + let bg_hermes_2 = hermes_2.background(); + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the samoleans have been sent from the first cosmos chain + check_cosmos_balance(&test_gaia_1, COSMOS_USER, "samoleans", 1000)?; + + // ------------------- Step 3. ------------------- + + let nam_addr = find_address(&test, NAM)?; + // we first send some NAM to the first cosmos chain. + let gaia_receiver = find_cosmos_address(&test_gaia_1, COSMOS_USER)?; + transfer( + &test, + BERTHA, + gaia_receiver, + NAM, + 20, + Some(BERTHA_KEY), + &port_id_namada, + &channel_id_namada_1, + None, + None, + None, + )?; + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_gaia_1, + &channel_id_gaia_1, + &test_gaia_1, + )?; + + // Check the NAM have been sent to the first cosmos chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000, + )?; + + // this will cause the ibc packet to be forwarded to the second + // cosmos chain. + let pfm_memo = packet_forward_memo( + "Hodor".to_string().into(), + &port_id_namada, + &channel_id_namada_2, + None, + ); + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 10_000_000, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the NAM have been refunded on the first chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000, + )?; + + // ------------------- Step 4. ------------------- + + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_2, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_2, + Some(Duration::new(1, 0)), + ); + // Stop Hermes for timeout test + let mut hermes_2 = bg_hermes_2.foreground(); + hermes_2.interrupt()?; + + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 10_000_000, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + + // wait for the timeout + sleep(10); + + // Restart relaying + let hermes_2 = run_hermes(&hermes_namada_gaia2)?; + let bg_hermes_2 = hermes_2.background(); + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the NAM have been refunded on the first chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!("transfer/{channel_id_gaia_1}/{nam_addr}"), + 20_000_000, + )?; + + // ------------------- Step 5. ------------------- + + // we first send some samoleans to the first cosmos chain from the second. + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_1, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_1, + None, + ); + transfer_from_cosmos( + &test_gaia_2, + COSMOS_USER, + &namada_receiver, + "samoleans", + 10, + &port_id_gaia_2, + &channel_id_gaia_2, + Some(Either::Right(pfm_memo)), + None, + )?; + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_gaia_1, + &channel_id_gaia_1, + &test_gaia_1, + )?; + + // Check the non-native samoleans have been sent to the first cosmos chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!( + "transfer/{channel_id_gaia_1}/transfer/{channel_id_namada_2}/\ + samoleans" + ), + 10, + )?; + + // this will cause the ibc packet to be forwarded to the second + // cosmos chain. + let pfm_memo = packet_forward_memo( + "Hodor".to_string().into(), + &port_id_namada, + &channel_id_namada_2, + None, + ); + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + format!( + "transfer/{channel_id_gaia_1}/transfer/{channel_id_namada_2}/\ + samoleans" + ), + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the non-native samoleans have been refunded on the first chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!( + "transfer/{channel_id_gaia_1}/transfer/{channel_id_namada_2}/\ + samoleans" + ), + 10, + )?; + + // ------------------- Step 6. ------------------- + let pfm_memo = packet_forward_memo( + find_cosmos_address(&test_gaia_2, COSMOS_USER)?.into(), + &port_id_namada, + &channel_id_namada_2, + Some(Duration::new(1, 0)), + ); + // Stop Hermes for timeout test + let mut hermes_2 = bg_hermes_2.foreground(); + hermes_2.interrupt()?; + + transfer_from_cosmos( + &test_gaia_1, + COSMOS_USER, + &namada_receiver, + format!( + "transfer/{channel_id_gaia_1}/transfer/{channel_id_namada_2}/\ + samoleans" + ), + 10, + &port_id_gaia_1, + &channel_id_gaia_1, + Some(Either::Right(pfm_memo)), + None, + )?; + + // wait for the timeout + sleep(10); + + // Restart relaying + let hermes_2 = run_hermes(&hermes_namada_gaia2)?; + let _bg_hermes_2 = hermes_2.background(); + + wait_for_packet_relay( + &hermes_gaia1_namada, + &port_id_namada, + &channel_id_namada_1, + &test, + )?; + wait_for_packet_relay( + &hermes_namada_gaia2, + &port_id_gaia_2, + &channel_id_gaia_2, + &test_gaia_2, + )?; + + // Check the non-native samoleans have been refunded on the first chain + check_cosmos_balance( + &test_gaia_1, + COSMOS_USER, + format!( + "transfer/{channel_id_gaia_1}/transfer/{channel_id_namada_2}/\ + samoleans" + ), + 10, + )?; + Ok(()) +} + fn run_namada_cosmos( chain_type: CosmosChainType, mut update_genesis: impl FnMut( @@ -1109,13 +1898,14 @@ fn run_namada_cosmos( // Cosmos let test_cosmos = setup_cosmos(chain_type)?; - let cosmos = run_cosmos(&test_cosmos)?; + let cosmos = run_cosmos(&test_cosmos, true)?; sleep(5); Ok((ledger, cosmos, test, test_cosmos)) } fn create_channel_with_hermes( + hermes_dir: &TestDir, test_a: &Test, test_b: &Test, port_id_a: &PortId, @@ -1145,7 +1935,7 @@ fn create_channel_with_hermes( "--yes", ]; - let mut hermes = run_hermes_cmd(test_a, args, Some(240))?; + let mut hermes = run_hermes_cmd(hermes_dir, args, Some(240))?; let (channel_id_a, channel_id_b) = get_channel_ids_from_hermes_output(&mut hermes)?; hermes.assert_success(); @@ -1167,35 +1957,32 @@ fn get_channel_ids_from_hermes_output( Ok((channel_id_a, channel_id_b)) } -fn run_hermes(test: &Test) -> Result { +fn run_hermes(hermes_dir: &TestDir) -> Result { let args = ["start"]; - let mut hermes = run_hermes_cmd(test, args, Some(40))?; + let mut hermes = run_hermes_cmd(hermes_dir, args, Some(40))?; hermes.exp_string("Hermes has started")?; Ok(hermes) } -fn run_cosmos(test: &Test) -> Result { +fn run_cosmos(test: &Test, kill: bool) -> Result { let chain_type = CosmosChainType::chain_type(test.net.chain_id.as_str())?; let cmd_path = chain_type.command_path(); // cosmos process is sometimes left lingering causing subsequent runs to // fail - std::process::Command::new("pkill") - .args(["-9", cmd_path]) - .output() - .unwrap(); - - let args = [ - "start", - "--pruning", - "nothing", - "--grpc.address", - "0.0.0.0:9090", - ]; + if kill { + std::process::Command::new("pkill") + .args(["-9", cmd_path]) + .output() + .unwrap(); + } + let port_arg = format!("0.0.0.0:{}", 9090 + chain_type.get_offset()); + let args = ["start", "--pruning", "nothing", "--grpc.address", &port_arg]; let cosmos = run_cosmos_cmd(test, args, Some(40))?; Ok(cosmos) } fn wait_for_packet_relay( + hermes_dir: &TestDir, port_id: &PortId, channel_id: &ChannelId, test: &Test, @@ -1214,7 +2001,7 @@ fn wait_for_packet_relay( ]; for _ in 0..10 { sleep(10); - let mut hermes = run_hermes_cmd(test, args, Some(40))?; + let mut hermes = run_hermes_cmd(hermes_dir, args, Some(40))?; // Check no pending packet if hermes .exp_string( @@ -1235,6 +2022,7 @@ fn wait_for_packet_relay( } fn clear_packet( + hermes_dir: &TestDir, port_id: &PortId, channel_id: &ChannelId, test: &Test, @@ -1249,14 +2037,14 @@ fn clear_packet( "--channel", channel_id.as_str(), ]; - let mut hermes = run_hermes_cmd(test, args, Some(40))?; + let mut hermes = run_hermes_cmd(hermes_dir, args, Some(40))?; hermes.assert_success(); Ok(()) } fn upgrade_client( - test: &Test, + hermes_dir: &TestDir, host_chain_id: impl AsRef, upgrade_height: u64, ) -> Result<()> { @@ -1270,7 +2058,7 @@ fn upgrade_client( "--upgrade-height", &upgrade_height.to_string(), ]; - let mut hermes = run_hermes_cmd(test, args, Some(120))?; + let mut hermes = run_hermes_cmd(hermes_dir, args, Some(120))?; hermes.exp_string("upgraded-chain")?; hermes.assert_success(); @@ -1646,7 +2434,7 @@ fn propose_upgrade_client( let proposal_json_path = test_gaia.test_dir.path().join("proposal.json"); write_json_file(proposal_json_path.as_path(), proposal_json); - let rpc = format!("tcp://{COSMOS_RPC}"); + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test_gaia)); let submit_proposal_args = vec![ "tx", "gov", @@ -1716,7 +2504,8 @@ fn propose_gas_token(test: &Test) -> Result { } fn wait_for_pass(test: &Test) -> Result<()> { - let args = ["query", "gov", "proposal", "1"]; + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); + let args = ["query", "gov", "proposal", "1", "--node", &rpc]; for _ in 0..10 { sleep(5); let mut gaia = run_cosmos_cmd(test, args, Some(40))?; @@ -1729,7 +2518,7 @@ fn wait_for_pass(test: &Test) -> Result<()> { } fn vote_on_gaia(test: &Test) -> Result<()> { - let rpc = format!("tcp://{COSMOS_RPC}"); + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); let args = vec![ "tx", "gov", @@ -1805,13 +2594,16 @@ fn transfer_from_cosmos( amount: u64, port_id: &PortId, channel_id: &ChannelId, - memo_path: Option, + memo: Option>, timeout_sec: Option, ) -> Result<()> { let port_id = port_id.to_string(); let channel_id = channel_id.to_string(); let amount = format!("{}{}", amount, token.as_ref()); - let rpc = format!("tcp://{COSMOS_RPC}"); + let offset = CosmosChainType::chain_type(test.net.chain_id.as_str()) + .unwrap() + .get_offset(); + let rpc = format!("tcp://127.0.0.1:6416{offset}"); // If the receiver is a pyament address we want to mask it to the more // general MASP internal address to improve on privacy let receiver = match PaymentAddress::from_str(receiver.as_ref()) { @@ -1839,13 +2631,16 @@ fn transfer_from_cosmos( "--yes", ]; - let memo = memo_path - .as_ref() - .map(|path| { - std::fs::read_to_string(path).expect("Reading memo file failed") + let is_memo = memo.is_some(); + let memo = memo + .map(|m| match m { + Either::Left(path) => { + std::fs::read_to_string(path).expect("Reading memo file failed") + } + Either::Right(memo) => memo, }) .unwrap_or_default(); - if memo_path.is_some() { + if is_memo { args.push("--memo"); args.push(&memo); } @@ -1886,7 +2681,10 @@ fn check_tx_height(test: &Test, client: &mut NamadaCmd) -> Result { } fn query_height(test: &Test) -> Result { - let rpc = get_actor_rpc(test, Who::Validator(0)); + let rpc = match CosmosChainType::chain_type(test.net.chain_id.as_str()) { + Ok(_) => format!("http://{}", get_cosmos_rpc_address(test)), + Err(_) => get_actor_rpc(test, Who::Validator(0)), + }; let tendermint_url = Url::from_str(&rpc).unwrap(); let client = HttpClient::new(tendermint_url).unwrap(); @@ -1941,14 +2739,11 @@ fn check_cosmos_balance( expected_amount: u64, ) -> Result<()> { let addr = find_cosmos_address(test, owner)?; - let args = [ - "query", - "bank", - "balances", - &addr, - "--node", - &format!("tcp://{COSMOS_RPC}"), - ]; + let offset = CosmosChainType::chain_type(test.net.chain_id.as_str()) + .unwrap() + .get_offset(); + let rpc = format!("tcp://127.0.0.1:6416{offset}"); + let args = ["query", "bank", "balances", &addr, "--node", &rpc]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; cosmos.exp_string(&format!("amount: \"{expected_amount}\""))?; let expected_denom = if denom.as_ref().contains('/') { @@ -2047,9 +2842,9 @@ fn initialize_nft_contracts(test: &Test) -> Result<(String, String)> { Ok(dir) => PathBuf::from(dir), Err(_) => working_dir(), }; - let rpc = format!("tcp://{COSMOS_RPC}"); + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); let minter_addr = find_cosmos_address(test, COSMOS_USER)?; - + sleep(5); // Store cw721 contract let cw721_wasm_path = contract_dir.join(CW721_WASM).to_string_lossy().to_string(); @@ -2076,7 +2871,7 @@ fn initialize_nft_contracts(test: &Test) -> Result<(String, String)> { ]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; cosmos.exp_eof()?; - sleep(1); + sleep(5); // Store ics721 contract let ics721_wasm_path = @@ -2106,10 +2901,6 @@ fn initialize_nft_contracts(test: &Test) -> Result<(String, String)> { cosmos.exp_eof()?; sleep(1); - let args = vec!["query", "wasm", "list-code"]; - let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; - cosmos.assert_success(); - // Instantiate cw721 contract let json = serde_json::json!({ "name": "test_nft", @@ -2178,17 +2969,32 @@ fn initialize_nft_contracts(test: &Test) -> Result<(String, String)> { ]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; cosmos.exp_eof()?; + sleep(1); // Check the CW721 contract - let args = vec!["query", "wasm", "list-contract-by-code", "1"]; + let args = vec![ + "query", + "wasm", + "list-contract-by-code", + "1", + "--node", + &rpc, + ]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; let (_unread, matched) = cosmos.exp_regex("wasm.*")?; let cw721_contract = matched.trim().to_string(); cosmos.exp_eof()?; // Check the ICS721 contract - let args = vec!["query", "wasm", "list-contract-by-code", "2"]; + let args = vec![ + "query", + "wasm", + "list-contract-by-code", + "2", + "--node", + &rpc, + ]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; let (_unread, matched) = cosmos.exp_regex("wasm.*")?; let ics721_contract = matched.trim().to_string(); @@ -2198,8 +3004,10 @@ fn initialize_nft_contracts(test: &Test) -> Result<(String, String)> { } fn get_cosmwasm_port_id(test: &Test, ics721_contract: &str) -> Result { + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); // Get the port ID - let args = vec!["query", "wasm", "contract", ics721_contract]; + let args = + vec!["query", "wasm", "contract", ics721_contract, "--node", &rpc]; let mut cosmos = run_cosmos_cmd(test, args, Some(40))?; let (_unread, matched) = cosmos.exp_regex("ibc_port_id: wasm.*")?; let port_id = matched.trim().split(' ').last().expect("invalid output"); @@ -2215,7 +3023,7 @@ fn mint_nft( minter_addr: &str, token_id: &str, ) -> Result<()> { - let rpc = format!("tcp://{COSMOS_RPC}"); + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); // Mint an NFT let json = serde_json::json!({ @@ -2268,7 +3076,7 @@ fn nft_transfer_from_cosmos( ) -> Result<()> { let channel_id = channel_id.to_string(); let timeout_height = timeout_height.unwrap_or(100000); - let rpc = format!("tcp://{COSMOS_RPC}"); + let rpc = format!("tcp://{}", get_cosmos_rpc_address(test)); let receiver = match PaymentAddress::from_str(receiver.as_ref()) { Ok(_) => MASP.to_string(), @@ -2331,3 +3139,27 @@ fn nft_transfer_from_cosmos( Ok(()) } + +/// Create a packet forward memo and serialize it +fn packet_forward_memo( + receiver: Signer, + port_id: &PortId, + channel_id: &ChannelId, + timeout: Option, +) -> String { + serde_json::to_string(&ibc_middleware_packet_forward::PacketMetadata { + forward: ForwardMetadata { + receiver, + port: port_id.clone(), + channel: channel_id.clone(), + timeout: timeout.map(|t| { + ibc_middleware_packet_forward::Duration::from_dur( + dur::Duration::from_std(t), + ) + }), + retries: Some(0), + next: None, + }, + }) + .expect("Test failed") +} diff --git a/crates/tests/src/e2e/setup.rs b/crates/tests/src/e2e/setup.rs index ebd2329aaa..2afa434069 100644 --- a/crates/tests/src/e2e/setup.rs +++ b/crates/tests/src/e2e/setup.rs @@ -1251,10 +1251,12 @@ pub fn sleep(seconds: u64) { thread::sleep(time::Duration::from_secs(seconds)); } -pub fn setup_hermes(test_a: &Test, test_b: &Test) -> Result<()> { +pub fn setup_hermes(test_a: &Test, test_b: &Test) -> Result { + let hermes_dir = TestDir::new(); + println!("\n{}", "Setting up Hermes".underline().green(),); - make_hermes_config(test_a, test_b)?; + make_hermes_config(&hermes_dir, test_a, test_b)?; for test in [test_a, test_b] { let chain_id = test.net.chain_id.as_str(); @@ -1267,20 +1269,21 @@ pub fn setup_hermes(test_a: &Test, test_b: &Test) -> Result<()> { let args = [ "keys", "add", + "--overwrite", "--chain", chain_id, "--key-file", &key_file_path.to_string_lossy(), ]; - let mut hermes = run_hermes_cmd(test, args, Some(20))?; + let mut hermes = run_hermes_cmd(&hermes_dir, args, Some(20))?; hermes.assert_success(); } - Ok(()) + Ok(hermes_dir) } pub fn run_hermes_cmd( - test: &Test, + hermes_dir: &TestDir, args: I, timeout_sec: Option, ) -> Result @@ -1289,7 +1292,8 @@ where S: AsRef, { let mut run_cmd = Command::new("hermes"); - let hermes_dir = test.test_dir.as_ref().join("hermes"); + let hermes_dir: &Path = hermes_dir.as_ref(); + let hermes_dir = hermes_dir.join("hermes"); run_cmd.current_dir(hermes_dir.clone()); let config_path = hermes_dir.join("config.toml"); run_cmd.args(["--config", &config_path.to_string_lossy()]); @@ -1312,7 +1316,7 @@ where let log_path = { let mut rng = rand::thread_rng(); - let log_dir = test.get_base_dir(Who::NonValidator).join("logs"); + let log_dir = hermes_dir.join("logs"); std::fs::create_dir_all(&log_dir)?; log_dir.join(format!( "{}-hermes-{}.log", @@ -1344,46 +1348,63 @@ where #[derive(Clone, Copy, Debug)] pub enum CosmosChainType { - Gaia, + Gaia(Option), CosmWasm, } impl CosmosChainType { - pub fn chain_id(&self) -> &str { + pub fn chain_id(&self) -> String { match self { - Self::Gaia => constants::GAIA_CHAIN_ID, - Self::CosmWasm => constants::COSMWASM_CHAIN_ID, + Self::Gaia(Some(suffix)) => { + format!("{}{}", constants::GAIA_CHAIN_ID, suffix) + } + Self::Gaia(_) => constants::GAIA_CHAIN_ID.to_string(), + Self::CosmWasm => constants::COSMWASM_CHAIN_ID.to_string(), } } pub fn command_path(&self) -> &str { match self { - Self::Gaia => "gaiad", + Self::Gaia(_) => "gaiad", Self::CosmWasm => "wasmd", } } pub fn chain_type(chain_id: &str) -> Result { - match chain_id { - constants::GAIA_CHAIN_ID => Ok(Self::Gaia), - constants::COSMWASM_CHAIN_ID => Ok(Self::CosmWasm), - _ => Err(eyre!(format!("Unexpected Cosmos chain ID: {chain_id}"))), + if chain_id == constants::COSMWASM_CHAIN_ID { + return Ok(Self::CosmWasm); + } + match chain_id.strip_prefix(constants::GAIA_CHAIN_ID) { + Some("") => Ok(Self::Gaia(None)), + Some(suffix) => { + Ok(Self::Gaia(Some(suffix.parse().map_err(|_| { + eyre!("Unexpected Cosmos chain ID: {chain_id}") + })?))) + } + _ => Err(eyre!("Unexpected Cosmos chain ID: {chain_id}")), } } pub fn account_prefix(&self) -> &str { match self { - Self::Gaia => "cosmos", + Self::Gaia(_) => "cosmos", Self::CosmWasm => "wasm", } } + + pub fn get_offset(&self) -> u64 { + match self { + Self::Gaia(Some(off)) => *off, + _ => 0, + } + } } pub fn setup_cosmos(chain_type: CosmosChainType) -> Result { let working_dir = working_dir(); let test_dir = TestDir::new(); let chain_id = chain_type.chain_id(); - let cosmos_dir = test_dir.as_ref().join(chain_id); + let cosmos_dir = test_dir.as_ref().join(&chain_id); let net = Network { chain_id: ChainId(chain_id.to_string()), }; @@ -1395,7 +1416,7 @@ pub fn setup_cosmos(chain_type: CosmosChainType) -> Result { }; // initialize - let args = ["--chain-id", chain_id, "init", chain_id]; + let args = ["--chain-id", &chain_id, "init", &chain_id]; let mut cosmos = run_cosmos_cmd(&test, args, Some(10))?; cosmos.assert_success(); @@ -1460,7 +1481,7 @@ pub fn setup_cosmos(chain_type: CosmosChainType) -> Result { "--keyring-backend", "test", "--chain-id", - chain_id, + &chain_id, ]; let mut cosmos = run_cosmos_cmd(&test, args, Some(10))?; cosmos.assert_success(); @@ -1592,7 +1613,7 @@ pub mod constants { // Gaia or CosmWasm pub const GAIA_CHAIN_ID: &str = "gaia"; pub const COSMWASM_CHAIN_ID: &str = "cosmwasm"; - pub const COSMOS_RPC: &str = "127.0.0.1:26657"; + pub const COSMOS_RPC: &str = "127.0.0.1:64160"; pub const COSMOS_USER: &str = "user"; pub const COSMOS_RELAYER: &str = "relayer"; pub const COSMOS_VALIDATOR: &str = "validator"; diff --git a/crates/tx_prelude/src/ibc.rs b/crates/tx_prelude/src/ibc.rs index 283dc0f723..436a6befc2 100644 --- a/crates/tx_prelude/src/ibc.rs +++ b/crates/tx_prelude/src/ibc.rs @@ -6,6 +6,7 @@ use std::rc::Rc; use namada_core::address::Address; use namada_core::token::Amount; +use namada_ibc::context::pfm_mod::PfmTransferModule; pub use namada_ibc::event::{IbcEvent, IbcEventType}; pub use namada_ibc::storage::{ burn_tokens, client_state_key, is_ibc_key, mint_limit_key, mint_tokens, @@ -19,7 +20,7 @@ pub use namada_ibc::{ }; use namada_tx_env::TxEnv; -use crate::{token, Ctx, Result}; +use crate::{parameters, token, Ctx, Result}; /// IBC actions to handle an IBC message. The `verifiers` inserted into the set /// must be inserted into the tx context with `Ctx::insert_verifier` after tx @@ -30,7 +31,10 @@ pub fn ibc_actions( let ctx = Rc::new(RefCell::new(ctx.clone())); let verifiers = Rc::new(RefCell::new(BTreeSet::
::new())); let mut actions = IbcActions::new(ctx.clone(), verifiers.clone()); - let module = TransferModule::new(ctx.clone(), verifiers); + let module = PfmTransferModule::<_, parameters::Store>::wrap( + ctx.clone(), + verifiers, + ); actions.add_transfer_module(module); let module = NftTransferModule::>::new(ctx); actions.add_transfer_module(module); diff --git a/wasm/Cargo.lock b/wasm/Cargo.lock index a31ac28ac3..07801fa2ed 100644 --- a/wasm/Cargo.lock +++ b/wasm/Cargo.lock @@ -1369,6 +1369,16 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" +[[package]] +name = "dur" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5b6c91b5e394b75cd96c36393fc938496c030220207a0ccf34d6cd313d3b49" +dependencies = [ + "nom", + "rust_decimal", +] + [[package]] name = "duration-str" version = "0.10.0" @@ -2554,7 +2564,7 @@ dependencies = [ [[package]] name = "ibc" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-apps", "ibc-clients", @@ -2567,7 +2577,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer-types", "ibc-core", @@ -2577,7 +2587,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "base64 0.22.1", "borsh", @@ -2598,7 +2608,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-transfer-types", "ibc-core", @@ -2608,7 +2618,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2626,7 +2636,7 @@ dependencies = [ [[package]] name = "ibc-apps" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer", "ibc-app-transfer", @@ -2635,7 +2645,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "ibc-client-tendermint-types", @@ -2652,7 +2662,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "displaydoc", "ibc-core-client-types", @@ -2669,7 +2679,7 @@ dependencies = [ [[package]] name = "ibc-client-wasm-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "base64 0.22.1", "displaydoc", @@ -2683,7 +2693,7 @@ dependencies = [ [[package]] name = "ibc-clients" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-tendermint", "ibc-client-wasm-types", @@ -2692,7 +2702,7 @@ dependencies = [ [[package]] name = "ibc-core" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -2708,7 +2718,7 @@ dependencies = [ [[package]] name = "ibc-core-channel" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel-types", "ibc-core-client", @@ -2723,7 +2733,7 @@ dependencies = [ [[package]] name = "ibc-core-channel-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2746,7 +2756,7 @@ dependencies = [ [[package]] name = "ibc-core-client" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-client-context", "ibc-core-client-types", @@ -2759,7 +2769,7 @@ dependencies = [ [[package]] name = "ibc-core-client-context" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -2775,7 +2785,7 @@ dependencies = [ [[package]] name = "ibc-core-client-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2795,7 +2805,7 @@ dependencies = [ [[package]] name = "ibc-core-commitment-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2814,7 +2824,7 @@ dependencies = [ [[package]] name = "ibc-core-connection" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-wasm-types", "ibc-core-client", @@ -2828,7 +2838,7 @@ dependencies = [ [[package]] name = "ibc-core-connection-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2849,7 +2859,7 @@ dependencies = [ [[package]] name = "ibc-core-handler" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -2864,7 +2874,7 @@ dependencies = [ [[package]] name = "ibc-core-handler-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2888,7 +2898,7 @@ dependencies = [ [[package]] name = "ibc-core-host" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -2906,7 +2916,7 @@ dependencies = [ [[package]] name = "ibc-core-host-cosmos" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -2929,7 +2939,7 @@ dependencies = [ [[package]] name = "ibc-core-host-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2944,7 +2954,7 @@ dependencies = [ [[package]] name = "ibc-core-router" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -2958,7 +2968,7 @@ dependencies = [ [[package]] name = "ibc-core-router-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -2977,17 +2987,36 @@ dependencies = [ [[package]] name = "ibc-derive" version = "0.8.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "proc-macro2", "quote", "syn 2.0.52", ] +[[package]] +name = "ibc-middleware-packet-forward" +version = "0.6.0" +source = "git+https://github.com/heliaxdev/ibc-middleware?tag=pfm/v0.6.0#ca824cfbe550c529d30bf27a97026dd0a058cfdf" +dependencies = [ + "borsh", + "dur", + "either", + "ibc-app-transfer-types", + "ibc-core-channel", + "ibc-core-channel-types", + "ibc-core-host-types", + "ibc-core-router", + "ibc-core-router-types", + "ibc-primitives", + "serde", + "serde_json", +] + [[package]] name = "ibc-primitives" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -3027,7 +3056,7 @@ dependencies = [ [[package]] name = "ibc-query" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "displaydoc", "ibc", @@ -3038,7 +3067,7 @@ dependencies = [ [[package]] name = "ibc-testkit" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "basecoin-store", "derive_more", @@ -3578,6 +3607,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -3778,8 +3813,10 @@ version = "0.46.0" dependencies = [ "borsh", "data-encoding", + "dur", "ibc", "ibc-derive", + "ibc-middleware-packet-forward", "ibc-testkit", "ics23", "konst", @@ -4064,7 +4101,9 @@ version = "0.46.0" dependencies = [ "concat-idents", "derivative", + "dur", "hyper 0.14.27", + "ibc-middleware-packet-forward", "ibc-testkit", "ics23", "itertools 0.12.1", @@ -4335,6 +4374,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nonempty" version = "0.7.0" @@ -5482,12 +5531,18 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.35.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" dependencies = [ "arrayvec", + "borsh", + "bytes", "num-traits 0.2.17", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", ] [[package]] @@ -5850,11 +5905,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] diff --git a/wasm_for_tests/Cargo.lock b/wasm_for_tests/Cargo.lock index f9acde8215..def2ae1b0d 100644 --- a/wasm_for_tests/Cargo.lock +++ b/wasm_for_tests/Cargo.lock @@ -23,6 +23,17 @@ dependencies = [ "cpufeatures", ] +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "aho-corasick" version = "1.1.2" @@ -389,6 +400,28 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -690,6 +723,16 @@ dependencies = [ "syn 2.0.65", ] +[[package]] +name = "dur" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce5b6c91b5e394b75cd96c36393fc938496c030220207a0ccf34d6cd313d3b49" +dependencies = [ + "nom", + "rust_decimal", +] + [[package]] name = "dyn-clone" version = "1.0.16" @@ -1033,6 +1076,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + [[package]] name = "hashbrown" version = "0.14.3" @@ -1106,7 +1158,7 @@ dependencies = [ [[package]] name = "ibc" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-apps", "ibc-clients", @@ -1119,7 +1171,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer-types", "ibc-core", @@ -1129,7 +1181,7 @@ dependencies = [ [[package]] name = "ibc-app-nft-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "base64 0.22.1", "borsh", @@ -1150,7 +1202,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-transfer-types", "ibc-core", @@ -1160,7 +1212,7 @@ dependencies = [ [[package]] name = "ibc-app-transfer-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1178,7 +1230,7 @@ dependencies = [ [[package]] name = "ibc-apps" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-app-nft-transfer", "ibc-app-transfer", @@ -1187,7 +1239,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "ibc-client-tendermint-types", @@ -1204,7 +1256,7 @@ dependencies = [ [[package]] name = "ibc-client-tendermint-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "displaydoc", "ibc-core-client-types", @@ -1221,7 +1273,7 @@ dependencies = [ [[package]] name = "ibc-client-wasm-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "base64 0.22.1", "displaydoc", @@ -1235,7 +1287,7 @@ dependencies = [ [[package]] name = "ibc-clients" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-tendermint", "ibc-client-wasm-types", @@ -1244,7 +1296,7 @@ dependencies = [ [[package]] name = "ibc-core" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -1260,7 +1312,7 @@ dependencies = [ [[package]] name = "ibc-core-channel" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel-types", "ibc-core-client", @@ -1275,7 +1327,7 @@ dependencies = [ [[package]] name = "ibc-core-channel-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1298,7 +1350,7 @@ dependencies = [ [[package]] name = "ibc-core-client" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-client-context", "ibc-core-client-types", @@ -1311,7 +1363,7 @@ dependencies = [ [[package]] name = "ibc-core-client-context" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -1327,7 +1379,7 @@ dependencies = [ [[package]] name = "ibc-core-client-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1347,7 +1399,7 @@ dependencies = [ [[package]] name = "ibc-core-commitment-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1366,7 +1418,7 @@ dependencies = [ [[package]] name = "ibc-core-connection" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-client-wasm-types", "ibc-core-client", @@ -1380,7 +1432,7 @@ dependencies = [ [[package]] name = "ibc-core-connection-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1401,7 +1453,7 @@ dependencies = [ [[package]] name = "ibc-core-handler" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "ibc-core-channel", "ibc-core-client", @@ -1416,7 +1468,7 @@ dependencies = [ [[package]] name = "ibc-core-handler-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1440,7 +1492,7 @@ dependencies = [ [[package]] name = "ibc-core-host" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -1458,7 +1510,7 @@ dependencies = [ [[package]] name = "ibc-core-host-cosmos" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -1481,7 +1533,7 @@ dependencies = [ [[package]] name = "ibc-core-host-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1496,7 +1548,7 @@ dependencies = [ [[package]] name = "ibc-core-router" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "derive_more", "displaydoc", @@ -1510,7 +1562,7 @@ dependencies = [ [[package]] name = "ibc-core-router-types" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1529,17 +1581,36 @@ dependencies = [ [[package]] name = "ibc-derive" version = "0.8.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "proc-macro2", "quote", "syn 2.0.65", ] +[[package]] +name = "ibc-middleware-packet-forward" +version = "0.6.0" +source = "git+https://github.com/heliaxdev/ibc-middleware?tag=pfm/v0.6.0#ca824cfbe550c529d30bf27a97026dd0a058cfdf" +dependencies = [ + "borsh", + "dur", + "either", + "ibc-app-transfer-types", + "ibc-core-channel", + "ibc-core-channel-types", + "ibc-core-host-types", + "ibc-core-router", + "ibc-core-router-types", + "ibc-primitives", + "serde", + "serde_json", +] + [[package]] name = "ibc-primitives" version = "0.54.0" -source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=38bd2a32f35117d4d9165a3c68c64ccd87ad56dd#38bd2a32f35117d4d9165a3c68c64ccd87ad56dd" +source = "git+https://github.com/heliaxdev/cosmos-ibc-rs?rev=aa229566e6bb688cc2626dab276c3849abc0c583#aa229566e6bb688cc2626dab276c3849abc0c583" dependencies = [ "borsh", "derive_more", @@ -1674,7 +1745,7 @@ source = "git+https://github.com/heliaxdev/indexmap?tag=2.2.4-heliax-1#b5b5b547b dependencies = [ "borsh", "equivalent", - "hashbrown", + "hashbrown 0.14.3", "serde", ] @@ -1685,7 +1756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", ] [[package]] @@ -1942,6 +2013,12 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "multimap" version = "0.8.3" @@ -2065,8 +2142,10 @@ version = "0.46.0" dependencies = [ "borsh", "data-encoding", + "dur", "ibc", "ibc-derive", + "ibc-middleware-packet-forward", "ics23", "konst", "masp_primitives", @@ -2402,6 +2481,16 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nonempty" version = "0.7.0" @@ -2876,6 +2965,26 @@ dependencies = [ "prost 0.13.2", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "quote" version = "1.0.36" @@ -3021,6 +3130,15 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -3040,6 +3158,35 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rlp" version = "0.5.2" @@ -3062,6 +3209,22 @@ dependencies = [ "svgbobdoc", ] +[[package]] +name = "rust_decimal" +version = "1.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b082d80e3e3cc52b2ed634388d436fe1f4de6af5786cc2de9ba9737527bdf555" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits 0.2.17", + "rand", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-hex" version = "2.1.0" @@ -3150,6 +3313,12 @@ dependencies = [ "syn 2.0.65", ] +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "sec1" version = "0.7.3" @@ -3234,11 +3403,12 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.108" +version = "1.0.133" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -3314,6 +3484,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "slab" version = "0.4.9" @@ -3902,6 +4078,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" + [[package]] name = "version_check" version = "0.9.4"