diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index ed489fddca..b53a6f6ff5 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -71,6 +71,7 @@ library Assets { payload = SubstrateTypes.SendToken(address(this), token, destinationChain, destinationAddress, amount); extraFee = $.sendTokenFee; + emit IGateway.TokenSent(sender, token, destinationChain, abi.encodePacked(destinationAddress), amount); } diff --git a/contracts/src/DeployScript.sol b/contracts/src/DeployScript.sol index 2efddbe9f9..813a5c3388 100644 --- a/contracts/src/DeployScript.sol +++ b/contracts/src/DeployScript.sol @@ -12,7 +12,7 @@ import {Gateway} from "./Gateway.sol"; import {GatewayUpgradeMock} from "../test/mocks/GatewayUpgradeMock.sol"; import {Agent} from "./Agent.sol"; import {AgentExecutor} from "./AgentExecutor.sol"; -import {ParaID, Config} from "./Types.sol"; +import {ParaID, Config, OperatingMode} from "./Types.sol"; import {SafeNativeTransfer} from "./utils/SafeTransfer.sol"; import {stdJson} from "forge-std/StdJson.sol"; @@ -66,8 +66,19 @@ contract DeployScript is Script { assetHubAgentID ); + bool rejectOutboundMessages = vm.envBool("REJECT_OUTBOUND_MESSAGES"); + OperatingMode defaultOperatingMode; + if (rejectOutboundMessages) { + defaultOperatingMode = OperatingMode.RejectingOutboundMessages; + } else { + defaultOperatingMode = OperatingMode.Normal; + } + bytes memory initParams = abi.encode( - vm.envUint("DEFAULT_FEE"), vm.envUint("REGISTER_NATIVE_TOKEN_FEE"), vm.envUint("SEND_NATIVE_TOKEN_FEE") + defaultOperatingMode, + vm.envUint("DEFAULT_FEE"), + vm.envUint("REGISTER_NATIVE_TOKEN_FEE"), + vm.envUint("SEND_NATIVE_TOKEN_FEE") ); GatewayProxy gateway = new GatewayProxy(address(gatewayLogic), initParams); diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 281304e73c..876a64db32 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -200,7 +200,7 @@ contract Gateway is IGateway, IInitializable { _transferNativeFromAgent(channel.agent, payable(msg.sender), amount); } - emit IGateway.InboundMessageDispatched(message.origin, message.nonce, success); + emit IGateway.InboundMessageDispatched(message.origin, message.nonce, message.id, success); } /** @@ -512,7 +512,10 @@ contract Gateway is IGateway, IInitializable { payable(msg.sender).safeNativeTransfer(msg.value - channel.fee - extraFee); } - emit IGateway.OutboundMessageAccepted(dest, channel.outboundNonce, payload); + // Generate a unique ID for this message + bytes32 messageID = keccak256(abi.encodePacked(dest, channel.outboundNonce)); + + emit IGateway.OutboundMessageAccepted(dest, channel.outboundNonce, messageID, payload); } /// @dev Outbound message can be disabled globally or on a per-channel basis. @@ -569,12 +572,12 @@ contract Gateway is IGateway, IInitializable { revert Unauthorized(); } - (uint256 defaultFee, uint256 registerTokenFee, uint256 sendTokenFee) = - abi.decode(data, (uint256, uint256, uint256)); + (OperatingMode defaultMode, uint256 defaultFee, uint256 registerTokenFee, uint256 sendTokenFee) = + abi.decode(data, (OperatingMode, uint256, uint256, uint256)); CoreStorage.Layout storage $ = CoreStorage.layout(); - $.mode = OperatingMode.RejectingOutboundMessages; + $.mode = defaultMode; $.defaultFee = defaultFee; // Initialize an agent & channel for BridgeHub diff --git a/contracts/src/Types.sol b/contracts/src/Types.sol index 6da4a56b5d..f38abdea44 100644 --- a/contracts/src/Types.sol +++ b/contracts/src/Types.sol @@ -45,6 +45,8 @@ struct InboundMessage { uint256 maxRefund; /// @dev The reward for message submission uint256 reward; + /// @dev ID for this message + bytes32 id; } enum OperatingMode { diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index 9230a29e5d..de7bad478c 100644 --- a/contracts/src/interfaces/IGateway.sol +++ b/contracts/src/interfaces/IGateway.sol @@ -11,10 +11,10 @@ interface IGateway { */ // Emitted when inbound message has been dispatched - event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bool success); + event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bytes32 indexed messageID, bool success); // Emitted when an outbound message has been accepted for delivery to a Polkadot parachain - event OutboundMessageAccepted(ParaID indexed destination, uint64 nonce, bytes payload); + event OutboundMessageAccepted(ParaID indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); // Emitted when an agent has been created for a consensus system on Polkadot event AgentCreated(bytes32 agentID, address agent); @@ -34,14 +34,6 @@ interface IGateway { // Emitted when funds are withdrawn from an agent event AgentFundsWithdrawn(bytes32 indexed agentID, address indexed recipient, uint256 amount); - // Emitted when the fees updated - event TokenTransferFeesChanged(uint256 register, uint256 send); - /// @dev Emitted once the funds are locked and a message is successfully queued. - event TokenSent( - address indexed token, address indexed sender, ParaID destinationChain, bytes destinationAddress, uint128 amount - ); - event TokenRegistrationSent(address token); - /** * Getters */ @@ -67,6 +59,19 @@ interface IGateway { /** * Token Transfers */ + + // @dev Emitted when the fees updated + event TokenTransferFeesChanged(uint256 register, uint256 send); + + /// @dev Emitted once the funds are locked and an outbound message is successfully queued. + event TokenSent( + address indexed token, address indexed sender, ParaID destinationChain, bytes destinationAddress, uint128 amount + ); + + /// @dev Emitted when a command is sent to register a new wrapped token on AssetHub + event TokenRegistrationSent(address token); + + // @dev Fees in Ether for registering and sending tokens respectively function tokenTransferFees() external view returns (uint256, uint256); /// @dev Send a message to the AssetHub parachain to register a new fungible asset diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index 2b1bcb573b..c53dc88bfe 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -28,20 +28,6 @@ import {WETH9} from "canonical-weth/WETH9.sol"; import "./mocks/GatewayUpgradeMock.sol"; contract GatewayTest is Test { - event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bool result); - event OutboundMessageAccepted(ParaID indexed dest, uint64 nonce, bytes payload); - event NativeTokensUnlocked(address token, address recipient, uint256 amount); - event TokenRegistrationSent(address token); - event TokenSent( - address indexed sender, address indexed token, ParaID destinationChain, bytes destinationAddress, uint128 amount - ); - event AgentCreated(bytes32 agentID, address agent); - event ChannelCreated(ParaID indexed paraID); - event ChannelUpdated(ParaID indexed paraID); - - event Upgraded(address indexed implementation); - event Initialized(uint256 d0, uint256 d1); - ParaID public bridgeHubParaID = ParaID.wrap(1001); bytes32 public bridgeHubAgentID = keccak256("1001"); address public bridgeHubAgent; @@ -66,6 +52,7 @@ contract GatewayTest is Test { uint256 public maxDispatchGas = 500_000; uint256 public maxRefund = 1 ether; uint256 public reward = 1 ether; + bytes32 public messageID = keccak256("cabbage"); uint256 public baseFee = 1 ether; uint256 public registerNativeTokenFee = 1 ether; @@ -84,6 +71,7 @@ contract GatewayTest is Test { gateway = new GatewayProxy( address(gatewayLogic), abi.encode( + OperatingMode.Normal, baseFee, registerNativeTokenFee, sendNativeTokenFee @@ -156,11 +144,11 @@ contract GatewayTest is Test { // Expect the gateway to emit `InboundMessageDispatched` vm.expectEmit(true, false, false, false); - emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, true); + emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, messageID, true); hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -173,7 +161,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -182,7 +170,7 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.InvalidNonce.selector); hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -194,7 +182,9 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.ChannelDoesNotExist.selector); hoax(relayer); IGateway(address(gateway)).submitInbound( - InboundMessage(ParaID.wrap(42), 1, command, "", maxDispatchGas, maxRefund, reward), proof, makeMockProof() + InboundMessage(ParaID.wrap(42), 1, command, "", maxDispatchGas, maxRefund, reward, messageID), + proof, + makeMockProof() ); } @@ -208,7 +198,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -231,7 +221,7 @@ contract GatewayTest is Test { uint256 startGas = gasleft(); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -257,7 +247,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -532,10 +522,10 @@ contract GatewayTest is Test { function testRegisterToken() public { vm.expectEmit(false, false, false, true); - emit TokenRegistrationSent(address(token)); + emit IGateway.TokenRegistrationSent(address(token)); vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, SubstrateTypes.RegisterToken(address(token))); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).registerToken{value: 2 ether}(address(token)); } @@ -545,7 +535,7 @@ contract GatewayTest is Test { emit IGateway.TokenRegistrationSent(address(token)); vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, SubstrateTypes.RegisterToken(address(token))); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); uint256 totalFee = baseFee + registerNativeTokenFee; uint256 balanceBefore = address(this).balance; @@ -571,9 +561,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted( - assetHubParaID, 1, SubstrateTypes.SendToken(address(token), destPara, destAddress, 1) - ); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -591,9 +579,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted( - assetHubParaID, 1, SubstrateTypes.SendToken(address(token), destAddress, 1) - ); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -611,7 +597,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, hex""); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -743,10 +729,10 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, true); // Expect dispatch result as false for `OutOfGas` - emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, false); + emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, messageID, false); // maxDispatchGas as 1 for `create_agent` is definitely not enough IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, 1, maxRefund, reward), proof, makeMockProof() + InboundMessage(bridgeHubParaID, 1, command, params, 1, maxRefund, reward, messageID), proof, makeMockProof() ); } diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 8732841b3f..6593791e25 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -59,6 +59,78 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloy-primitives" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +dependencies = [ + "alloy-rlp-derive", + "arrayvec 0.7.2", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-rlp-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.38", + "syn-solidity", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "amcl" version = "0.3.0" @@ -122,8 +194,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -133,9 +205,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -144,10 +216,10 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", "itertools", @@ -163,8 +235,26 @@ checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c" dependencies = [ "ark-bls12-381", "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", ] [[package]] @@ -173,20 +263,30 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "digest 0.10.7", "itertools", "num-bigint", "num-traits", "paste", - "rustc_version", + "rustc_version 0.4.0", "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.4.2" @@ -197,6 +297,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-macros" version = "0.4.2" @@ -216,9 +328,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", ] @@ -230,9 +342,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51bd73bb6ddb72630987d37fa963e99196896c0d0ea81b7c894567e74a2f83af" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "parity-scale-codec", "scale-info", ] @@ -243,15 +355,25 @@ version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "ark-transcript", "digest 0.10.7", "rand_core 0.6.4", "zeroize", ] +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + [[package]] name = "ark-serialize" version = "0.4.2" @@ -259,7 +381,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.4.0", "digest 0.10.7", "num-bigint", ] @@ -275,6 +397,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "ark-std" version = "0.4.0" @@ -290,9 +422,9 @@ name = "ark-transcript" version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "digest 0.10.7", "rand_core 0.6.4", "sha3", @@ -350,6 +482,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -379,9 +523,9 @@ dependencies = [ "ark-bls12-381", "ark-ec", "ark-ed-on-bls12-381-bandersnatch", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "dleq_vrf", "fflonk", "merlin 3.0.0", @@ -432,6 +576,21 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" @@ -444,6 +603,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitvec" version = "1.0.1" @@ -643,10 +808,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/ring-proof#edd1e90b847e560bf60fc2e8712235ccfa11a9a9" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "fflonk", "merlin 3.0.0", "rand_chacha 0.3.1", @@ -668,6 +833,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.2" @@ -840,7 +1018,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "platforms", - "rustc_version", + "rustc_version 0.4.0", "subtle", "zeroize", ] @@ -941,7 +1119,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -980,11 +1158,11 @@ version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-scale", "ark-secret-scalar", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "ark-transcript", "arrayvec 0.7.2", "rand_core 0.6.4", @@ -1018,6 +1196,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "dyn-clonable" version = "0.9.0" @@ -1155,6 +1339,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -1230,6 +1424,23 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec 0.7.2", + "auto_impl", + "bytes", +] + [[package]] name = "ff" version = "0.13.0" @@ -1246,10 +1457,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/fflonk#e141d4b6f42fb481aefe1b479788694945b6940d" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "merlin 3.0.0", ] @@ -1271,6 +1482,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -1321,7 +1538,7 @@ name = "frame-support" version = "4.0.0-dev" dependencies = [ "aquamarine", - "bitflags", + "bitflags 1.3.2", "docify", "environmental", "frame-metadata", @@ -1833,7 +2050,7 @@ checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1894,6 +2111,12 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libsecp256k1" version = "0.7.1" @@ -1966,6 +2189,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "lock_api" version = "0.4.9" @@ -2069,7 +2298,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix", + "rustix 0.36.11", ] [[package]] @@ -2223,11 +2452,12 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2393,9 +2623,9 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2419,6 +2649,17 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2573,6 +2814,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.7.5", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "psm" version = "0.1.21" @@ -2582,6 +2843,12 @@ dependencies = [ "cc", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.33" @@ -2668,6 +2935,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -2680,7 +2956,16 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -2711,7 +2996,7 @@ checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.6.28", ] [[package]] @@ -2720,7 +3005,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.28", ] [[package]] @@ -2729,6 +3014,12 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "rfc6979" version = "0.4.0" @@ -2745,10 +3036,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/ring-proof#edd1e90b847e560bf60fc2e8712235ccfa11a9a9" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "blake2", "common", "fflonk", @@ -2765,6 +3056,36 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "ruint" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "724fd11728a3804e9944b14cab63825024c40bf42f8af87c8b5d97c4bbacf426" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -2777,13 +3098,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.17", ] [[package]] @@ -2792,12 +3122,25 @@ version = "0.36.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" dependencies = [ - "bitflags", - "errno", + "bitflags 1.3.2", + "errno 0.2.8", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno 0.3.5", + "libc", + "linux-raw-sys 0.4.10", + "windows-sys 0.48.0", ] [[package]] @@ -2806,6 +3149,18 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.12" @@ -2944,12 +3299,30 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.190" @@ -3092,6 +3465,15 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + [[package]] name = "snowbridge-beacon-primitives" version = "0.0.1" @@ -3236,14 +3618,17 @@ dependencies = [ name = "snowbridge-inbound-queue" version = "0.1.1" dependencies = [ - "ethabi-decode", + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", "frame-benchmarking", "frame-support", "frame-system", "hex-literal", + "log", + "num-traits", "pallet-balances", "parity-scale-codec", - "rlp", "scale-info", "serde", "snowbridge-beacon-primitives", @@ -3423,7 +3808,7 @@ dependencies = [ "array-bytes 6.1.0", "bandersnatch_vrfs", "bip39", - "bitflags", + "bitflags 1.3.2", "blake2", "bounded-collections", "bs58", @@ -3973,6 +4358,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -3997,6 +4394,19 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix 0.38.21", + "windows-sys 0.48.0", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -4225,6 +4635,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uint" version = "0.9.5" @@ -4237,6 +4653,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -4302,8 +4724,8 @@ dependencies = [ "ark-bls12-377", "ark-bls12-381", "ark-ec", - "ark-ff", - "ark-serialize", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", "ark-serialize-derive", "arrayref", "constcat", @@ -4317,6 +4739,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -4462,7 +4893,7 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4513,7 +4944,7 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4533,7 +4964,7 @@ checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" dependencies = [ "cfg-if", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4553,11 +4984,11 @@ dependencies = [ "memoffset", "paste", "rand 0.8.5", - "rustix", + "rustix 0.36.11", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4629,7 +5060,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -4638,13 +5078,28 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4653,42 +5108,84 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "winnow" version = "0.5.17" @@ -4719,9 +5216,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] diff --git a/parachain/pallets/control/src/lib.rs b/parachain/pallets/control/src/lib.rs index 57a62d46f9..9e632b03c3 100644 --- a/parachain/pallets/control/src/lib.rs +++ b/parachain/pallets/control/src/lib.rs @@ -459,7 +459,7 @@ pub mod pallet { impl Pallet { /// Send `command` to the Gateway on the channel identified by `origin`. fn send(origin: ParaId, command: Command, pays_fee: PaysFee) -> DispatchResult { - let message = Message { origin, command }; + let message = Message { id: None, origin, command }; let (ticket, fee) = T::OutboundQueue::validate(&message).map_err(|err| Error::::Send(err))?; diff --git a/parachain/pallets/control/src/tests.rs b/parachain/pallets/control/src/tests.rs index 92548f9ee9..10be9b3a65 100644 --- a/parachain/pallets/control/src/tests.rs +++ b/parachain/pallets/control/src/tests.rs @@ -520,8 +520,11 @@ fn charge_fee_for_create_agent() { assert_ok!(EthereumControl::create_agent(origin.clone())); // assert sovereign_balance decreased by (fee.base_fee + fee.delivery_fee) - let message = - Message { origin: para_id.into(), command: Command::CreateAgent { agent_id } }; + let message = Message { + id: None, + origin: para_id.into(), + command: Command::CreateAgent { agent_id }, + }; let (_, fee) = OutboundQueue::validate(&message).unwrap(); let sovereign_balance = Balances::balance(&sovereign_account); assert_eq!(sovereign_balance + fee.local + fee.remote, InitialFunding::get()); @@ -555,6 +558,7 @@ fn charge_fee_for_transfer_native_from_agent() { let sovereign_balance_before = Balances::balance(&sovereign_account); assert_ok!(EthereumControl::transfer_native_from_agent(origin.clone(), recipient, amount)); let message = Message { + id: None, origin: para_id.into(), command: Command::TransferNativeFromAgent { agent_id, recipient, amount }, }; diff --git a/parachain/pallets/ethereum-beacon-client/Cargo.toml b/parachain/pallets/ethereum-beacon-client/Cargo.toml index e3a20829cb..f4318a293c 100644 --- a/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/parachain/pallets/ethereum-beacon-client/Cargo.toml @@ -18,7 +18,7 @@ scale-info = { version = "2.9.0", default-features = false, features = [ "derive ssz_rs = { version="0.9.0", default-features = false } ssz_rs_derive = { version="0.9.0", default-features = false } byte-slice-cast = { version = "1.2.1", default-features = false } -rlp = { version = "0.5", default-features = false } +rlp = { version = "0.5.2", default-features = false } hex-literal = { version = "0.4.1", optional = true } log = { version = "0.4.20", default-features = false } diff --git a/parachain/pallets/ethereum-beacon-client/src/impls.rs b/parachain/pallets/ethereum-beacon-client/src/impls.rs index 571c0f9f7c..35b2e287de 100644 --- a/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/parachain/pallets/ethereum-beacon-client/src/impls.rs @@ -2,23 +2,23 @@ // SPDX-FileCopyrightText: 2023 Snowfork use super::*; -use snowbridge_ethereum::{Log, Receipt}; -use sp_runtime::DispatchError; +use snowbridge_core::inbound::VerificationError::{self, *}; +use snowbridge_ethereum::Receipt; impl Verifier for Pallet { /// Verify a message by verifying the existence of the corresponding /// Ethereum log in a block. Returns the log if successful. The execution header containing /// the log should be in the beacon client storage, meaning it has been verified and is an /// ancestor of a finalized beacon block. - fn verify(message: &Message) -> Result { + fn verify(message: &Message) -> Result<(), VerificationError> { log::info!( target: "ethereum-beacon-client", "💫 Verifying message with block hash {}", message.proof.block_hash, ); - let header = >::get(message.proof.block_hash) - .ok_or(Error::::MissingHeader)?; + let header = + >::get(message.proof.block_hash).ok_or(HeaderNotFound)?; let receipt = match Self::verify_receipt_inclusion(header.receipts_root, &message.proof) { Ok(receipt) => receipt, @@ -48,7 +48,7 @@ impl Verifier for Pallet { message.proof.block_hash, err ); - return Err(Error::::DecodeFailed.into()) + return Err(InvalidLog) }, }; @@ -58,7 +58,7 @@ impl Verifier for Pallet { "💫 Event log not found in receipt for transaction at index {} in block {}", message.proof.tx_index, message.proof.block_hash, ); - return Err(Error::::InvalidProof.into()) + return Err(LogNotFound) } log::info!( @@ -67,7 +67,7 @@ impl Verifier for Pallet { message.proof.block_hash, ); - Ok(log) + Ok(()) } } @@ -77,9 +77,8 @@ impl Pallet { pub fn verify_receipt_inclusion( receipts_root: H256, proof: &Proof, - ) -> Result { - let result = - verify_receipt_proof(receipts_root, &proof.data.1).ok_or(Error::::InvalidProof)?; + ) -> Result { + let result = verify_receipt_proof(receipts_root, &proof.data.1).ok_or(InvalidProof)?; match result { Ok(receipt) => Ok(receipt), @@ -89,7 +88,7 @@ impl Pallet { "💫 Failed to decode transaction receipt: {}", err ); - Err(Error::::InvalidProof.into()) + Err(InvalidProof) }, } } diff --git a/parachain/pallets/ethereum-beacon-client/src/lib.rs b/parachain/pallets/ethereum-beacon-client/src/lib.rs index 9c0d435624..0f3cf025b5 100644 --- a/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/parachain/pallets/ethereum-beacon-client/src/lib.rs @@ -134,9 +134,6 @@ pub mod pallet { InvalidAncestryMerkleProof, InvalidBlockRootsRootMerkleProof, HeaderNotFinalized, - MissingHeader, - InvalidProof, - DecodeFailed, BlockBodyHashTreeRootFailed, HeaderHashTreeRootFailed, SyncCommitteeHashTreeRootFailed, diff --git a/parachain/pallets/ethereum-beacon-client/src/tests.rs b/parachain/pallets/ethereum-beacon-client/src/tests.rs index 32cf0d485d..95a7c38229 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -16,7 +16,10 @@ use primitives::{ CompactExecutionHeader, ExecutionHeaderState, Fork, ForkVersions, NextSyncCommitteeUpdate, }; use rand::{thread_rng, Rng}; -use snowbridge_core::{inbound::Verifier, RingBufferMap}; +use snowbridge_core::{ + inbound::{VerificationError, Verifier}, + RingBufferMap, +}; use sp_core::H256; use sp_runtime::DispatchError; @@ -922,7 +925,7 @@ fn verify_message_missing_header() { let message = get_message_verification_payload(); new_tester().execute_with(|| { - assert_err!(EthereumBeaconClient::verify(&message), Error::::MissingHeader); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::HeaderNotFound); }); } @@ -935,7 +938,7 @@ fn verify_message_invalid_proof() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); }); } @@ -948,7 +951,7 @@ fn verify_message_invalid_receipts_root() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); }); } @@ -961,7 +964,7 @@ fn verify_message_invalid_message_data() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::DecodeFailed); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidLog); }); } @@ -974,7 +977,7 @@ fn verify_message_receipt_does_not_contain_log() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::LogNotFound); }); } diff --git a/parachain/pallets/inbound-queue/Cargo.toml b/parachain/pallets/inbound-queue/Cargo.toml index 0f3da50660..688d392499 100644 --- a/parachain/pallets/inbound-queue/Cargo.toml +++ b/parachain/pallets/inbound-queue/Cargo.toml @@ -14,7 +14,11 @@ serde = { version = "1.0.188", optional = true } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = [ "derive" ] } scale-info = { version = "2.9.0", default-features = false, features = [ "derive" ] } hex-literal = { version = "0.4.1", optional = true } -rlp = { version = "0.5", default-features = false, optional = true } +log = { version = "0.4.20", default-features = false } +alloy-primitives = { version = "0.4.2", default-features = false, features = ["rlp"] } +alloy-sol-types = { version = "0.4.2", default-features = false } +alloy-rlp = { version = "0.3.3", default-features = false, features = ["derive"] } +num-traits = { version = "0.2.16", default-features = false } frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../polkadot-sdk/substrate/frame/support", default-features = false } @@ -31,7 +35,6 @@ xcm-builder = { package = "staging-xcm-builder", path = "../../../polkadot-sdk/p snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } snowbridge-router-primitives = { path = "../../primitives/router", default-features = false } -ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false, optional = true } [dev-dependencies] @@ -39,16 +42,18 @@ frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarkin sp-keyring = { path = "../../../polkadot-sdk/substrate/primitives/keyring" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" } snowbridge-ethereum-beacon-client = { path = "../../pallets/ethereum-beacon-client" } - hex-literal = { version = "0.4.1" } -rlp = { version = "0.5" } [features] default = ["std"] std = [ "serde", + "log/std", "codec/std", "scale-info/std", + "alloy-primitives/std", + "alloy-sol-types/std", + "alloy-rlp/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -57,10 +62,10 @@ std = [ "sp-runtime/std", "sp-std/std", "sp-io/std", + "num-traits/std", "snowbridge-core/std", "snowbridge-ethereum/std", "snowbridge-router-primitives/std", - "ethabi/std", "xcm/std", "xcm-builder/std", ] @@ -70,7 +75,6 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", - "rlp", "snowbridge-beacon-primitives", "xcm-builder/runtime-benchmarks", ] diff --git a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs index ae1e00fb2a..11da799df8 100644 --- a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs +++ b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs @@ -17,7 +17,7 @@ pub fn make_create_message() -> InboundQueueTest { receipts_root: hex!("0115ab735d37c5e4cdb0374d8bb547c6dd6ccaa996d996d1eabc5399a719219e").into(), }, message: Message { - data: hex!("f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").to_vec(), + data: hex!("f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").to_vec(), proof: Proof { block_hash: hex!("5f465744c166e9d10dc0031942a59ff82b640053253da517a1b576afdadb0363").into(), tx_index: 0, diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index 3ce9dfd71d..e12ecf6c0f 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -1,22 +1,24 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -use ethabi::{Event, Param, ParamKind, Token}; use snowbridge_core::ParaId; -use snowbridge_ethereum::{log::Log, H160}; -use sp_core::RuntimeDebug; +use sp_core::{RuntimeDebug, H160, H256}; use sp_std::{convert::TryFrom, prelude::*}; -// Used to decode an OutboundMessageAccepted log into an [`Envelope`]. -static EVENT_ABI: &Event = &Event { - signature: "OutboundMessageAccepted(uint256,uint64,bytes)", - inputs: &[ - Param { kind: ParamKind::Uint(256), indexed: true }, - Param { kind: ParamKind::Uint(64), indexed: false }, - Param { kind: ParamKind::Bytes, indexed: false }, - ], - anonymous: false, -}; +use alloy_primitives::{Address, Bytes, B256}; +use alloy_rlp::RlpDecodable; +use alloy_sol_types::{sol, SolEvent}; + +#[derive(RlpDecodable, RuntimeDebug)] +pub struct Log { + pub address: Address, + pub topics: Vec, + pub data: Bytes, +} + +sol! { + event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); +} /// An inbound message that has had its outer envelope decoded. #[derive(Clone, RuntimeDebug)] @@ -27,36 +29,28 @@ pub struct Envelope { pub dest: ParaId, /// A nonce for enforcing replay protection and ordering. pub nonce: u64, + /// An id for tracing the message on its route (has no role in bridge consensus) + pub message_id: H256, /// The inner payload generated from the source application. pub payload: Vec, } -#[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug)] +#[derive(Copy, Clone, RuntimeDebug)] pub struct EnvelopeDecodeError; impl TryFrom for Envelope { type Error = EnvelopeDecodeError; fn try_from(log: Log) -> Result { - let tokens = EVENT_ABI.decode(log.topics, log.data).map_err(|_| EnvelopeDecodeError)?; - - let mut iter = tokens.into_iter(); - - let dest = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Uint(dest) => dest.low_u32().into(), - _ => return Err(EnvelopeDecodeError), - }; - - let nonce = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Uint(nonce) => nonce.low_u64(), - _ => return Err(EnvelopeDecodeError), - }; - - let payload = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Bytes(payload) => payload, - _ => return Err(EnvelopeDecodeError), - }; - - Ok(Self { gateway: log.address, dest, nonce, payload }) + let event = OutboundMessageAccepted::decode_log(log.topics, &log.data, true) + .map_err(|_| EnvelopeDecodeError)?; + + Ok(Self { + gateway: H160::from(log.address.as_ref()), + dest: event.destination.saturating_to::().into(), + nonce: event.nonce, + message_id: H256::from(event.messageID.as_ref()), + payload: event.payload, + }) } } diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index d937efe8b7..6cdef8eb29 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -30,42 +30,42 @@ mod benchmarking; #[cfg(feature = "runtime-benchmarks")] use snowbridge_beacon_primitives::CompactExecutionHeader; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_ethereum::H256; pub mod weights; #[cfg(test)] mod test; +use alloy_rlp::Decodable as RlpDecodable; use codec::{Decode, DecodeAll, Encode}; +use envelope::{Envelope, Log}; use frame_support::{ - traits::fungible::{Inspect, Mutate}, + traits::{ + fungible::{Inspect, Mutate}, + tokens::Preservation, + }, + weights::WeightToFee, PalletError, }; use frame_system::ensure_signed; use scale_info::TypeInfo; -use sp_core::H160; -use sp_std::convert::TryFrom; +use sp_core::{H160, H256}; +use sp_std::{convert::TryFrom, vec}; use xcm::prelude::{ - send_xcm, Junction::*, Junctions::*, MultiLocation, SendError as XcmpSendError, SendXcm, Xcm, - XcmHash, + send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, + SendError as XcmpSendError, SendXcm, Xcm, XcmHash, }; -use envelope::Envelope; use snowbridge_core::{ - inbound::{Message, Verifier}, + inbound::{Message, VerificationError, Verifier}, sibling_sovereign_account, BasicOperatingMode, ParaId, }; use snowbridge_router_primitives::{ inbound, inbound::{ConvertMessage, ConvertMessageError}, }; - use sp_runtime::traits::Saturating; -use frame_support::{traits::tokens::Preservation, weights::WeightToFee}; - pub use weights::WeightInfo; type BalanceOf = @@ -136,8 +136,8 @@ pub mod pallet { dest: ParaId, /// The message nonce nonce: u64, - /// XCM hash - xcm_hash: XcmHash, + /// ID of the XCM message which was forwarded to the final destination parachain + message_id: [u8; 32], }, /// Set OperatingMode OperatingModeChanged { mode: BasicOperatingMode }, @@ -159,6 +159,8 @@ pub mod pallet { InvalidAccountConversion, /// Pallet is halted Halted, + /// Message verification error, + Verification(VerificationError), /// XCMP send failure Send(SendError), /// Message conversion error @@ -211,7 +213,10 @@ pub mod pallet { ensure!(!Self::operating_mode().is_halted(), Error::::Halted); // submit message to verifier for verification - let log = T::Verifier::verify(&message)?; + T::Verifier::verify(&message).map_err(|e| Error::::Verification(e))?; + + let log = Log::decode(&mut message.data.as_slice()) + .map_err(|_| Error::::InvalidEnvelope)?; // Decode log into an Envelope let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope)?; @@ -245,17 +250,17 @@ pub mod pallet { // Decode message into XCM let xcm = match inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()) { - Ok(message) => Self::do_convert(message)?, + Ok(message) => Self::do_convert(envelope.message_id, message)?, Err(_) => return Err(Error::::InvalidPayload.into()), }; // Attempt to send XCM to a dest parachain - let xcm_hash = Self::send_xcm(xcm, envelope.dest)?; + let message_id = Self::send_xcm(xcm, envelope.dest)?; Self::deposit_event(Event::MessageReceived { dest: envelope.dest, nonce: envelope.nonce, - xcm_hash, + message_id, }); Ok(()) @@ -276,9 +281,14 @@ pub mod pallet { } impl Pallet { - pub fn do_convert(message: inbound::VersionedMessage) -> Result, Error> { - let xcm = + pub fn do_convert( + message_id: H256, + message: inbound::VersionedMessage, + ) -> Result, Error> { + let mut xcm = T::MessageConverter::convert(message).map_err(|e| Error::::ConvertMessage(e))?; + // Append the message id as an XCM topic + xcm.inner_mut().extend(vec![SetTopic(message_id.into())]); Ok(xcm) } diff --git a/parachain/pallets/inbound-queue/src/test.rs b/parachain/pallets/inbound-queue/src/test.rs index 59db735ffa..e7b3224b65 100644 --- a/parachain/pallets/inbound-queue/src/test.rs +++ b/parachain/pallets/inbound-queue/src/test.rs @@ -10,10 +10,9 @@ use frame_support::{ use hex_literal::hex; use snowbridge_beacon_primitives::{Fork, ForkVersions}; use snowbridge_core::{ - inbound::{Message, Proof}, + inbound::{Message, Proof, VerificationError}, ParaId, }; -use snowbridge_ethereum::Log; use snowbridge_router_primitives::inbound::MessageToXcm; use sp_core::{H160, H256}; use sp_keyring::AccountKeyring as Keyring; @@ -24,7 +23,7 @@ use sp_runtime::{ use sp_std::convert::From; use xcm::v3::{prelude::*, MultiAssets, SendXcm}; -use crate::{self as inbound_queue, envelope::Envelope, Error, Event as InboundQueueEvent}; +use crate::{self as inbound_queue, Error, Event as InboundQueueEvent}; type Block = frame_system::mocking::MockBlock; @@ -121,9 +120,8 @@ impl snowbridge_ethereum_beacon_client::Config for Test { pub struct MockVerifier; impl Verifier for MockVerifier { - fn verify(message: &Message) -> Result { - let log: Log = rlp::decode(&message.data).unwrap(); - Ok(log) + fn verify(_: &Message) -> Result<(), VerificationError> { + Ok(()) } } @@ -221,53 +219,30 @@ pub fn new_tester() -> sp_io::TestExternalities { ext } -fn parse_dest(message: Message) -> ParaId { - let log = MockVerifier::verify(&message) - .map_err(|err| { - println!("mock verify: {:?}", err); - err - }) - .unwrap(); - let envelope = Envelope::try_from(log) - .map_err(|err| { - println!("envelope: {:?}", err); - err - }) - .unwrap(); - envelope.dest -} - // dest para is 1000 -const OUTBOUND_QUEUE_EVENT_LOG: [u8; 221] = hex!( +const OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); // dest para is 1001 -const OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST: [u8; 221] = hex!( +const OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST: [u8; 254] = hex!( " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e9b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e9a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); -// gateway in message does not match configured gateway in runtime -const BAD_OUTBOUND_QUEUE_EVENT_LOG: [u8; 221] = hex!( +// gateway in message does not match configured gateway in runtimeå +const BAD_OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( " - f8db940000000000000000000000000000000000000000f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 - " -); - -// invalid payload with unsupported version -const BAD_OUTBOUND_QUEUE_LOG_UNSUPPORTED_VERSION: [u8; 221] = hex!( - " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e010f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc940000000000000000000000000000000000000000f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); const XCM_HASH: [u8; 32] = [ - 186, 27, 67, 39, 117, 164, 224, 191, 202, 232, 218, 108, 34, 65, 36, 199, 247, 19, 150, 198, - 182, 180, 39, 112, 150, 64, 84, 15, 174, 213, 183, 207, + 201, 101, 244, 67, 153, 61, 253, 203, 92, 23, 197, 172, 112, 209, 53, 248, 118, 25, 253, 110, + 168, 201, 60, 156, 227, 26, 55, 145, 5, 177, 78, 189, ]; const ASSET_HUB_PARAID: u32 = 1000u32; const TEMPLATE_PARAID: u32 = 1001u32; @@ -296,7 +271,7 @@ fn test_submit_happy_path() { expect_events(vec![InboundQueueEvent::MessageReceived { dest: ASSET_HUB_PARAID.into(), nonce: 1, - xcm_hash: XCM_HASH, + message_id: XCM_HASH, } .into()]); }); @@ -376,8 +351,7 @@ fn test_submit_with_invalid_nonce() { }; assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); - let event_dest = parse_dest(message.clone()); - let nonce: u64 = >::get(event_dest); + let nonce: u64 = >::get(ParaId::from(1000)); assert_eq!(nonce, 1); // Submit the same again @@ -414,62 +388,6 @@ fn test_submit_no_funds_to_reward_relayers() { }); } -#[test] -fn test_convert_xcm_message() { - new_tester().execute_with(|| { - // Submit message - let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), - proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), - }, - }; - let log = ::Verifier::verify(&message).unwrap(); - - // Decode log into an Envelope - let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope).unwrap(); - - let message = - inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()).unwrap(); - - let xcm = ::MessageConverter::convert(message).unwrap(); - - println!("xcm: {:?}", xcm); - - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - - assert_eq!(hash, XCM_HASH); - }) -} - -#[test] -fn test_submit_with_invalid_payload_unsupported_version() { - new_tester().execute_with(|| { - let relayer: AccountId = Keyring::Bob.into(); - let origin = RuntimeOrigin::signed(relayer); - - // Deposit funds into sovereign account of Asset Hub (Statemint) - let sovereign_account = sibling_sovereign_account::(ASSET_HUB_PARAID.into()); - let _ = Balances::mint_into(&sovereign_account, 10000); - - // Submit message - let message = Message { - data: BAD_OUTBOUND_QUEUE_LOG_UNSUPPORTED_VERSION.into(), - proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), - }, - }; - assert_noop!( - InboundQueue::submit(origin.clone(), message.clone()), - Error::::InvalidPayload - ); - }); -} - #[test] fn test_set_operating_mode() { new_tester().execute_with(|| { diff --git a/parachain/pallets/outbound-queue/src/benchmarking.rs b/parachain/pallets/outbound-queue/src/benchmarking.rs index 9fead12bfc..921507425f 100644 --- a/parachain/pallets/outbound-queue/src/benchmarking.rs +++ b/parachain/pallets/outbound-queue/src/benchmarking.rs @@ -21,7 +21,7 @@ mod benchmarks { #[benchmark] fn do_process_message() -> Result<(), BenchmarkError> { let enqueued_message = QueuedMessage { - id: H256::zero().into(), + id: H256::zero(), origin: 1000.into(), command: Command::Upgrade { impl_address: H160::zero(), diff --git a/parachain/pallets/outbound-queue/src/lib.rs b/parachain/pallets/outbound-queue/src/lib.rs index 283e13d9c6..2b9fb6b8ff 100644 --- a/parachain/pallets/outbound-queue/src/lib.rs +++ b/parachain/pallets/outbound-queue/src/lib.rs @@ -173,7 +173,7 @@ pub mod pallet { pub enum Event { /// Message has been queued and will be processed in the future MessageQueued { - /// ID of the message. Usually the XCM message hash. + /// ID of the message. Usually the XCM message hash or a SetTopic. id: H256, }, /// Message will be committed at the end of current block. From now on, to track the @@ -352,30 +352,31 @@ pub mod pallet { } // Decode bytes into versioned message - let versioned_enqueued_message: VersionedQueuedMessage = + let versioned_queued_message: VersionedQueuedMessage = VersionedQueuedMessage::decode(&mut message).map_err(|_| Corrupt)?; // Convert versioned message into latest supported message version - let enqueued_message: QueuedMessage = - versioned_enqueued_message.try_into().map_err(|_| Unsupported)?; + let queued_message: QueuedMessage = + versioned_queued_message.try_into().map_err(|_| Unsupported)?; - let next_nonce = Nonce::::get(enqueued_message.origin).saturating_add(1); + let next_nonce = Nonce::::get(queued_message.origin).saturating_add(1); - let command = enqueued_message.command.index(); - let params = enqueued_message.command.abi_encode(); - let max_dispatch_gas = T::GasMeter::maximum_required(&enqueued_message.command) as u128; - let max_refund = Self::calculate_maximum_gas_refund(&enqueued_message.command); + let command = queued_message.command.index(); + let params = queued_message.command.abi_encode(); + let max_dispatch_gas = T::GasMeter::maximum_required(&queued_message.command) as u128; + let max_refund = Self::calculate_maximum_gas_refund(&queued_message.command); let reward = Self::fee_config().reward; // Construct the final committed message let message = CommittedMessage { - origin: enqueued_message.origin, + origin: queued_message.origin, nonce: next_nonce, command, params, max_dispatch_gas, max_refund, reward, + id: queued_message.id, }; // ABI-encode and hash the prepared message @@ -384,10 +385,10 @@ pub mod pallet { Messages::::append(Box::new(message)); MessageLeaves::::append(message_abi_encoded_hash); - Nonce::::set(enqueued_message.origin, next_nonce); + Nonce::::set(queued_message.origin, next_nonce); Self::deposit_event(Event::MessageAccepted { - id: enqueued_message.id, + id: queued_message.id, nonce: next_nonce, }); diff --git a/parachain/pallets/outbound-queue/src/mock.rs b/parachain/pallets/outbound-queue/src/mock.rs index 8b7d0b3f30..1bd5dbfd43 100644 --- a/parachain/pallets/outbound-queue/src/mock.rs +++ b/parachain/pallets/outbound-queue/src/mock.rs @@ -127,6 +127,7 @@ where T: Config, { Message { + id: None, origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -142,6 +143,7 @@ where T: Config, { Message { + id: None, origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -156,6 +158,7 @@ where pub fn mock_message(sibling_para_id: u32) -> Message { Message { + id: None, origin: sibling_para_id.into(), command: Command::AgentExecute { agent_id: Default::default(), diff --git a/parachain/pallets/outbound-queue/src/send_message_impl.rs b/parachain/pallets/outbound-queue/src/send_message_impl.rs index 4912b9100e..ed4dbd2e4f 100644 --- a/parachain/pallets/outbound-queue/src/send_message_impl.rs +++ b/parachain/pallets/outbound-queue/src/send_message_impl.rs @@ -6,6 +6,7 @@ use frame_support::{ traits::{EnqueueMessage, Get}, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, }; +use frame_system::unique; use snowbridge_core::outbound::{ AggregateMessageOrigin, ExportOrigin, Fee, Message, QueuedMessage, SendError, SendMessage, VersionedQueuedMessage, @@ -18,28 +19,35 @@ pub type MaxEnqueuedMessageSizeOf = <::MessageQueue as EnqueueMessage>::MaxMessageLen; #[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound)] -pub struct Ticket> { - pub id: H256, +pub struct Ticket +where + T: Config, +{ + pub message_id: H256, pub origin: ParaId, - pub message: BoundedVec, + pub message: BoundedVec>, } -impl SendMessage for Pallet { - type Ticket = Ticket>; +impl SendMessage for Pallet +where + T: Config, +{ + type Ticket = Ticket; type Balance = T::Balance; fn validate(message: &Message) -> Result<(Self::Ticket, Fee), SendError> { // The inner payload should not be too large let payload = message.command.abi_encode(); - // Create a message id for tracking progress in submission pipeline - let message_id: H256 = sp_io::hashing::blake2_256(&(message.encode())).into(); - ensure!( payload.len() < T::MaxMessagePayloadSize::get() as usize, SendError::MessageTooLarge ); + // Generate a unique message id unless one is provided + let message_id: H256 = + message.id.unwrap_or_else(|| unique((message.origin, &message.command)).into()); + let fee = Self::calculate_fee(&message.command); let queued_message: VersionedQueuedMessage = QueuedMessage { @@ -51,7 +59,7 @@ impl SendMessage for Pallet { // The whole message should not be too large let encoded = queued_message.encode().try_into().map_err(|_| SendError::MessageTooLarge)?; - let ticket = Ticket { id: message_id, origin: message.origin, message: encoded }; + let ticket = Ticket { message_id, origin: message.origin, message: encoded }; Ok((ticket, fee)) } @@ -79,7 +87,7 @@ impl SendMessage for Pallet { let message = ticket.message.as_bounded_slice(); T::MessageQueue::enqueue_message(message, origin); - Self::deposit_event(Event::MessageQueued { id: ticket.id }); - Ok(ticket.id) + Self::deposit_event(Event::MessageQueued { id: ticket.message_id }); + Ok(ticket.message_id) } } diff --git a/parachain/pallets/outbound-queue/src/types.rs b/parachain/pallets/outbound-queue/src/types.rs index bdfd51e942..db75a2c6b5 100644 --- a/parachain/pallets/outbound-queue/src/types.rs +++ b/parachain/pallets/outbound-queue/src/types.rs @@ -4,6 +4,7 @@ use frame_support::traits::ProcessMessage; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_arithmetic::FixedU128; +use sp_core::H256; use sp_runtime::{traits::Zero, RuntimeDebug}; use sp_std::prelude::*; @@ -33,6 +34,8 @@ pub struct CommittedMessage { pub max_refund: u128, /// Reward in ether for delivering this message, in addition to the gas refund pub reward: u128, + /// Message ID (Used for tracing messages across route, has no role in consensus) + pub id: H256, } /// Convert message into an ABI-encoded form for delivery to the InboundQueue contract on Ethereum @@ -46,6 +49,7 @@ impl From for Token { Token::Uint(x.max_dispatch_gas.into()), Token::Uint(x.max_refund.into()), Token::Uint(x.reward.into()), + Token::FixedBytes(Vec::from(x.id.as_ref())), ]) } } diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index 5e7b10c25b..bc28c7e3bb 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -3,36 +3,43 @@ //! Types for representing inbound messages use codec::{Decode, Encode}; +use frame_support::PalletError; use scale_info::TypeInfo; -use snowbridge_ethereum::Log; use sp_core::H256; -use sp_runtime::{DispatchError, RuntimeDebug}; +use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; /// A trait for verifying inbound messages from Ethereum. -/// -/// This trait should be implemented by runtime modules that wish to provide message verification -/// functionality. pub trait Verifier { - fn verify(message: &Message) -> Result; + fn verify(message: &Message) -> Result<(), VerificationError>; +} + +#[derive(Clone, Encode, Decode, RuntimeDebug, PalletError, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum VerificationError { + /// Execution header is missing + HeaderNotFound, + /// Log was not found in the verified transaction receipt + LogNotFound, + /// Data payload does not decode into a valid Log + InvalidLog, + /// Unable to verify the transaction receipt with the provided proof + InvalidProof, } pub type MessageNonce = u64; -/// A message relayed from Ethereum. -#[derive(PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +/// A bridge message from the Gateway contract on Ethereum +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Message { - /// The raw RLP-encoded message data. + /// RLP-encoded event log pub data: Vec, - /// Input to the message verifier + /// Inclusion proof for a transaction receipt containing the event log pub proof: Proof, } -/// Verification input for the message verifier. -/// -/// This data type allows us to support multiple verification schemes. In the near future, -/// A light-client scheme will be added too. -#[derive(PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +/// Inclusion proof for a transaction receipt +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Proof { // The block hash of the block in which the receipt was included. pub block_hash: H256, diff --git a/parachain/primitives/core/src/outbound.rs b/parachain/primitives/core/src/outbound.rs index 21964e758e..71e5995fda 100644 --- a/parachain/primitives/core/src/outbound.rs +++ b/parachain/primitives/core/src/outbound.rs @@ -4,7 +4,6 @@ pub use polkadot_parachain_primitives::primitives::Id as ParaId; use scale_info::TypeInfo; use sp_arithmetic::traits::{BaseArithmetic, Unsigned}; use sp_core::{RuntimeDebug, H256}; - pub use v1::{AgentExecuteCommand, Command, Initializer, Message, OperatingMode, QueuedMessage}; /// Enqueued outbound messages need to be versioned to prevent data corruption @@ -39,10 +38,17 @@ mod v1 { use sp_core::{RuntimeDebug, H160, H256, U256}; use sp_std::{borrow::ToOwned, vec, vec::Vec}; - /// A message which can be accepted by the [`OutboundQueue`] + /// A message which can be accepted by implementations of [`SendMessage`] #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct Message { + /// ID for this message. One will be automatically generated if not provided. + /// + /// When this message is created from an XCM message, the ID should be extracted + /// from the `SetTopic` instruction. + /// + /// The ID plays no role in bridge consensus, and is purely meant for message tracing. + pub id: Option, /// The parachain from which the message originated pub origin: ParaId, /// The stable ID for a receiving gateway contract @@ -56,7 +62,7 @@ mod v1 { } /// A command which is executable by the Gateway contract on Ethereum - #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub enum Command { /// Execute a sub-command within an agent for a consensus system in Polkadot @@ -189,7 +195,7 @@ mod v1 { /// Representation of a call to the initializer of an implementation contract. /// The initializer has the following ABI signature: `initialize(bytes)`. - #[derive(Encode, Decode, TypeInfo, PartialEq, Clone, RuntimeDebug)] + #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Initializer { /// ABI-encoded params of type `bytes` to pass to the initializer pub params: Vec, @@ -198,7 +204,8 @@ mod v1 { } /// A Sub-command executable within an agent - #[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + #[cfg_attr(feature = "std", derive(PartialEq))] pub enum AgentExecuteCommand { /// Transfer ERC20 tokens TransferToken { @@ -235,10 +242,10 @@ mod v1 { } /// Message which is awaiting processing in the MessageQueue pallet - #[derive(Encode, Decode, Clone, RuntimeDebug, TypeInfo)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct QueuedMessage { - /// Message ID (usually hash of message) + /// Message ID pub id: H256, /// ID of source parachain pub origin: ParaId, @@ -291,6 +298,10 @@ pub trait SendMessage { fn deliver(ticket: Self::Ticket) -> Result; } +pub trait Ticket: Encode + Decode + Clone { + fn message_id(&self) -> H256; +} + /// Reasons why sending to Ethereum could not be initiated #[derive(Copy, Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, PalletError, TypeInfo)] pub enum SendError { diff --git a/parachain/primitives/ethereum/Cargo.toml b/parachain/primitives/ethereum/Cargo.toml index 7ff906b19a..832a7bffe0 100644 --- a/parachain/primitives/ethereum/Cargo.toml +++ b/parachain/primitives/ethereum/Cargo.toml @@ -14,8 +14,7 @@ ethereum-types = { version = "0.14.1", default-features = false, features = [ "c hex = { package = "rustc-hex", version = "2.1.0", default-features = false } hex-literal = { version = "0.4.1", default-features = false } parity-bytes = { version = "0.1.2", default-features = false } -rlp = { version = "0.5", default-features = false } -#getrandom = { version = "0.2.1", features = [ "js" ] } +rlp = { version = "0.5.2", default-features = false } sp-io = { path = "../../../polkadot-sdk/substrate/primitives/io", default-features = false } sp-std = { path = "../../../polkadot-sdk/substrate/primitives/std", default-features = false } diff --git a/parachain/primitives/router/Cargo.toml b/parachain/primitives/router/Cargo.toml index 3a93e709bf..056a33d2ca 100644 --- a/parachain/primitives/router/Cargo.toml +++ b/parachain/primitives/router/Cargo.toml @@ -47,6 +47,7 @@ std = [ "xcm-executor/std", "snowbridge-core/std", "ethabi/std", + "log/std", ] runtime-benchmarks = [ "snowbridge-core/runtime-benchmarks", diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index 54447cb01f..235ea98c71 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -83,6 +83,7 @@ pub enum ConvertMessageError { /// convert the inbound message to xcm which will be forwarded to the destination chain pub trait ConvertMessage { + /// Converts a versioned message into an XCM message and an optional topicID fn convert(message: VersionedMessage) -> Result, ConvertMessageError>; } diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index 99bb027664..80e61dae5c 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -25,7 +25,6 @@ where UniversalLocation: Get, EthereumNetwork: Get, OutboundQueue: SendMessage, - OutboundQueue::Ticket: Encode + Decode, AgentHashedDescription: ConvertLocation, { type Ticket = (Vec, XcmHash); @@ -82,7 +81,7 @@ where })?; let mut converter = XcmConverter::new(&message, &expected_network); - let agent_execute_command = converter.convert().map_err(|err|{ + let (agent_execute_command, message_id) = converter.convert().map_err(|err|{ log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to pattern matching error '{err:?}'."); SendError::Unroutable })?; @@ -98,6 +97,7 @@ where }; let outbound_message = Message { + id: Some(message_id.into()), origin: para_id.into(), command: Command::AgentExecute { agent_id, command: agent_execute_command }, }; @@ -111,7 +111,7 @@ where // convert fee to MultiAsset let fee = MultiAsset::from((MultiLocation::parent(), fee.total())).into(); - Ok(((ticket.encode(), XcmHash::default()), fee)) + Ok(((ticket.encode(), message_id), fee)) } fn deliver(blob: (Vec, XcmHash)) -> Result { @@ -121,13 +121,13 @@ where SendError::NotApplicable })?; - let message_hash = OutboundQueue::deliver(ticket).map_err(|_| { + let message_id = OutboundQueue::deliver(ticket).map_err(|_| { log::error!(target: "xcm::ethereum_blob_exporter", "OutboundQueue submit of message failed"); SendError::Transport("other transport error") })?; - log::info!(target: "xcm::ethereum_blob_exporter", "message delivered {message_hash:#?}."); - Ok(message_hash.into()) + log::info!(target: "xcm::ethereum_blob_exporter", "message delivered {message_id:#?}."); + Ok(message_id.into()) } } @@ -166,7 +166,7 @@ impl<'a, Call> XcmConverter<'a, Call> { Self { iter: message.inner().iter().peekable(), ethereum_network } } - fn convert(&mut self) -> Result { + fn convert(&mut self) -> Result<(AgentExecuteCommand, [u8; 32]), XcmConverterError> { // Get withdraw/deposit and make native tokens create message. let result = self.native_tokens_unlock_message()?; @@ -178,7 +178,9 @@ impl<'a, Call> XcmConverter<'a, Call> { Ok(result) } - fn native_tokens_unlock_message(&mut self) -> Result { + fn native_tokens_unlock_message( + &mut self, + ) -> Result<(AgentExecuteCommand, [u8; 32]), XcmConverterError> { use XcmConverterError::*; // Get the reserve assets from WithdrawAsset. @@ -249,10 +251,9 @@ impl<'a, Call> XcmConverter<'a, Call> { ensure!(amount > 0, ZeroAssetTransfer); // Check if there is a SetTopic and skip over it if found. - let _topic_id = - match_expression!(self.next()?, SetTopic(id), id).ok_or(SetTopicExpected)?; + let topic_id = match_expression!(self.next()?, SetTopic(id), id).ok_or(SetTopicExpected)?; - Ok(AgentExecuteCommand::TransferToken { token, recipient, amount }) + Ok((AgentExecuteCommand::TransferToken { token, recipient, amount }, *topic_id)) } fn next(&mut self) -> Result<&'a Instruction, XcmConverterError> { @@ -285,6 +286,7 @@ mod tests { use super::*; parameter_types! { + const MaxMessageSize: u32 = u32::MAX; const RelayNetwork: NetworkId = Polkadot; const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(1013)); const BridgedNetwork: NetworkId = Ethereum{ chain_id: 1 }; @@ -296,7 +298,7 @@ mod tests { type Ticket = (); type Balance = u128; - fn validate(_: &Message) -> Result<((), Fee), SendError> { + fn validate(_: &Message) -> Result<(Self::Ticket, Fee), SendError> { Ok(((), Fee { local: 1, remote: 1 })) } @@ -309,7 +311,7 @@ mod tests { type Ticket = (); type Balance = u128; - fn validate(_: &Message) -> Result<((), Fee), SendError> { + fn validate(_: &Message) -> Result<(Self::Ticket, Fee), SendError> { Err(SendError::MessageTooLarge) } @@ -683,7 +685,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok(expected_payload)); + assert_eq!(result, Ok((expected_payload, [0; 32]))); } #[test] @@ -716,7 +718,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok(expected_payload)); + assert_eq!(result, Ok((expected_payload, [0; 32]))); } #[test] @@ -751,7 +753,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok(expected_payload)); + assert_eq!(result, Ok((expected_payload, [0; 32]))); } #[test] @@ -787,7 +789,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok(expected_payload)); + assert_eq!(result, Ok((expected_payload, [0; 32]))); } #[test] diff --git a/polkadot-sdk b/polkadot-sdk index cc24f53f01..464bf57bfb 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit cc24f53f01101260aa41432c3b67211c9d363fac +Subproject commit 464bf57bfb368e3089248d0bec3db75d5f8de613 diff --git a/relayer/contracts/gateway.go b/relayer/contracts/gateway.go index dd85c3d772..7b01b9f831 100644 --- a/relayer/contracts/gateway.go +++ b/relayer/contracts/gateway.go @@ -38,6 +38,7 @@ type InboundMessage struct { MaxDispatchGas *big.Int MaxRefund *big.Int Reward *big.Int + Id [32]byte } // VerificationDigestItem is an auto generated low-level Go binding around an user-defined struct. @@ -84,7 +85,7 @@ type VerificationProof struct { // GatewayMetaData contains all meta data concerning the Gateway contract. var GatewayMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"register\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"send\",\"type\":\"uint256\"}],\"name\":\"SetTokenTransferFees\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokenTransferFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"register\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"send\",\"type\":\"uint256\"}],\"name\":\"TokenTransferFeesChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tokenTransferFees\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } // GatewayABI is the input ABI used to generate the binding from. @@ -515,23 +516,23 @@ func (_Gateway *GatewayTransactorSession) SendToken0(token common.Address, desti return _Gateway.Contract.SendToken0(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewayTransactor) SubmitInbound(opts *bind.TransactOpts, message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.contract.Transact(opts, "submitInbound", message, leafProof, headerProof) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewaySession) SubmitInbound(message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.Contract.SubmitInbound(&_Gateway.TransactOpts, message, leafProof, headerProof) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewayTransactorSession) SubmitInbound(message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.Contract.SubmitInbound(&_Gateway.TransactOpts, message, leafProof, headerProof) } @@ -1182,40 +1183,51 @@ func (it *GatewayInboundMessageDispatchedIterator) Close() error { // GatewayInboundMessageDispatched represents a InboundMessageDispatched event raised by the Gateway contract. type GatewayInboundMessageDispatched struct { - Origin *big.Int - Nonce uint64 - Success bool - Raw types.Log // Blockchain specific contextual infos + Origin *big.Int + Nonce uint64 + MessageID [32]byte + Success bool + Raw types.Log // Blockchain specific contextual infos } -// FilterInboundMessageDispatched is a free log retrieval operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// FilterInboundMessageDispatched is a free log retrieval operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) -func (_Gateway *GatewayFilterer) FilterInboundMessageDispatched(opts *bind.FilterOpts, origin []*big.Int) (*GatewayInboundMessageDispatchedIterator, error) { +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) +func (_Gateway *GatewayFilterer) FilterInboundMessageDispatched(opts *bind.FilterOpts, origin []*big.Int, messageID [][32]byte) (*GatewayInboundMessageDispatchedIterator, error) { var originRule []interface{} for _, originItem := range origin { originRule = append(originRule, originItem) } - logs, sub, err := _Gateway.contract.FilterLogs(opts, "InboundMessageDispatched", originRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "InboundMessageDispatched", originRule, messageIDRule) if err != nil { return nil, err } return &GatewayInboundMessageDispatchedIterator{contract: _Gateway.contract, event: "InboundMessageDispatched", logs: logs, sub: sub}, nil } -// WatchInboundMessageDispatched is a free log subscription operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// WatchInboundMessageDispatched is a free log subscription operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) -func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchOpts, sink chan<- *GatewayInboundMessageDispatched, origin []*big.Int) (event.Subscription, error) { +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) +func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchOpts, sink chan<- *GatewayInboundMessageDispatched, origin []*big.Int, messageID [][32]byte) (event.Subscription, error) { var originRule []interface{} for _, originItem := range origin { originRule = append(originRule, originItem) } - logs, sub, err := _Gateway.contract.WatchLogs(opts, "InboundMessageDispatched", originRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "InboundMessageDispatched", originRule, messageIDRule) if err != nil { return nil, err } @@ -1247,9 +1259,9 @@ func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchO }), nil } -// ParseInboundMessageDispatched is a log parse operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// ParseInboundMessageDispatched is a log parse operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) func (_Gateway *GatewayFilterer) ParseInboundMessageDispatched(log types.Log) (*GatewayInboundMessageDispatched, error) { event := new(GatewayInboundMessageDispatched) if err := _Gateway.contract.UnpackLog(event, "InboundMessageDispatched", log); err != nil { @@ -1464,38 +1476,49 @@ func (it *GatewayOutboundMessageAcceptedIterator) Close() error { type GatewayOutboundMessageAccepted struct { Destination *big.Int Nonce uint64 + MessageID [32]byte Payload []byte Raw types.Log // Blockchain specific contextual infos } -// FilterOutboundMessageAccepted is a free log retrieval operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// FilterOutboundMessageAccepted is a free log retrieval operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, destination []*big.Int) (*GatewayOutboundMessageAcceptedIterator, error) { +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) +func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, destination []*big.Int, messageID [][32]byte) (*GatewayOutboundMessageAcceptedIterator, error) { var destinationRule []interface{} for _, destinationItem := range destination { destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destinationRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destinationRule, messageIDRule) if err != nil { return nil, err } return &GatewayOutboundMessageAcceptedIterator{contract: _Gateway.contract, event: "OutboundMessageAccepted", logs: logs, sub: sub}, nil } -// WatchOutboundMessageAccepted is a free log subscription operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// WatchOutboundMessageAccepted is a free log subscription operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOpts, sink chan<- *GatewayOutboundMessageAccepted, destination []*big.Int) (event.Subscription, error) { +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) +func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOpts, sink chan<- *GatewayOutboundMessageAccepted, destination []*big.Int, messageID [][32]byte) (event.Subscription, error) { var destinationRule []interface{} for _, destinationItem := range destination { destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destinationRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destinationRule, messageIDRule) if err != nil { return nil, err } @@ -1527,9 +1550,9 @@ func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOp }), nil } -// ParseOutboundMessageAccepted is a log parse operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// ParseOutboundMessageAccepted is a log parse operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) func (_Gateway *GatewayFilterer) ParseOutboundMessageAccepted(log types.Log) (*GatewayOutboundMessageAccepted, error) { event := new(GatewayOutboundMessageAccepted) if err := _Gateway.contract.UnpackLog(event, "OutboundMessageAccepted", log); err != nil { @@ -1539,9 +1562,9 @@ func (_Gateway *GatewayFilterer) ParseOutboundMessageAccepted(log types.Log) (*G return event, nil } -// GatewaySetTokenTransferFeesIterator is returned from FilterSetTokenTransferFees and is used to iterate over the raw logs and unpacked data for SetTokenTransferFees events raised by the Gateway contract. -type GatewaySetTokenTransferFeesIterator struct { - Event *GatewaySetTokenTransferFees // Event containing the contract specifics and raw log +// GatewayTokenRegistrationSentIterator is returned from FilterTokenRegistrationSent and is used to iterate over the raw logs and unpacked data for TokenRegistrationSent events raised by the Gateway contract. +type GatewayTokenRegistrationSentIterator struct { + Event *GatewayTokenRegistrationSent // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1555,7 +1578,7 @@ type GatewaySetTokenTransferFeesIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *GatewaySetTokenTransferFeesIterator) Next() bool { +func (it *GatewayTokenRegistrationSentIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1564,7 +1587,7 @@ func (it *GatewaySetTokenTransferFeesIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(GatewaySetTokenTransferFees) + it.Event = new(GatewayTokenRegistrationSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1579,7 +1602,7 @@ func (it *GatewaySetTokenTransferFeesIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(GatewaySetTokenTransferFees) + it.Event = new(GatewayTokenRegistrationSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1595,42 +1618,41 @@ func (it *GatewaySetTokenTransferFeesIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *GatewaySetTokenTransferFeesIterator) Error() error { +func (it *GatewayTokenRegistrationSentIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *GatewaySetTokenTransferFeesIterator) Close() error { +func (it *GatewayTokenRegistrationSentIterator) Close() error { it.sub.Unsubscribe() return nil } -// GatewaySetTokenTransferFees represents a SetTokenTransferFees event raised by the Gateway contract. -type GatewaySetTokenTransferFees struct { - Register *big.Int - Send *big.Int - Raw types.Log // Blockchain specific contextual infos +// GatewayTokenRegistrationSent represents a TokenRegistrationSent event raised by the Gateway contract. +type GatewayTokenRegistrationSent struct { + Token common.Address + Raw types.Log // Blockchain specific contextual infos } -// FilterSetTokenTransferFees is a free log retrieval operation binding the contract event 0xe1a86b0b703265be7e2b8f52a38625965fc66f6d52413944bdb9c815caaa932a. +// FilterTokenRegistrationSent is a free log retrieval operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. // -// Solidity: event SetTokenTransferFees(uint256 register, uint256 send) -func (_Gateway *GatewayFilterer) FilterSetTokenTransferFees(opts *bind.FilterOpts) (*GatewaySetTokenTransferFeesIterator, error) { +// Solidity: event TokenRegistrationSent(address token) +func (_Gateway *GatewayFilterer) FilterTokenRegistrationSent(opts *bind.FilterOpts) (*GatewayTokenRegistrationSentIterator, error) { - logs, sub, err := _Gateway.contract.FilterLogs(opts, "SetTokenTransferFees") + logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenRegistrationSent") if err != nil { return nil, err } - return &GatewaySetTokenTransferFeesIterator{contract: _Gateway.contract, event: "SetTokenTransferFees", logs: logs, sub: sub}, nil + return &GatewayTokenRegistrationSentIterator{contract: _Gateway.contract, event: "TokenRegistrationSent", logs: logs, sub: sub}, nil } -// WatchSetTokenTransferFees is a free log subscription operation binding the contract event 0xe1a86b0b703265be7e2b8f52a38625965fc66f6d52413944bdb9c815caaa932a. +// WatchTokenRegistrationSent is a free log subscription operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. // -// Solidity: event SetTokenTransferFees(uint256 register, uint256 send) -func (_Gateway *GatewayFilterer) WatchSetTokenTransferFees(opts *bind.WatchOpts, sink chan<- *GatewaySetTokenTransferFees) (event.Subscription, error) { +// Solidity: event TokenRegistrationSent(address token) +func (_Gateway *GatewayFilterer) WatchTokenRegistrationSent(opts *bind.WatchOpts, sink chan<- *GatewayTokenRegistrationSent) (event.Subscription, error) { - logs, sub, err := _Gateway.contract.WatchLogs(opts, "SetTokenTransferFees") + logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenRegistrationSent") if err != nil { return nil, err } @@ -1640,8 +1662,8 @@ func (_Gateway *GatewayFilterer) WatchSetTokenTransferFees(opts *bind.WatchOpts, select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(GatewaySetTokenTransferFees) - if err := _Gateway.contract.UnpackLog(event, "SetTokenTransferFees", log); err != nil { + event := new(GatewayTokenRegistrationSent) + if err := _Gateway.contract.UnpackLog(event, "TokenRegistrationSent", log); err != nil { return err } event.Raw = log @@ -1662,21 +1684,21 @@ func (_Gateway *GatewayFilterer) WatchSetTokenTransferFees(opts *bind.WatchOpts, }), nil } -// ParseSetTokenTransferFees is a log parse operation binding the contract event 0xe1a86b0b703265be7e2b8f52a38625965fc66f6d52413944bdb9c815caaa932a. +// ParseTokenRegistrationSent is a log parse operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. // -// Solidity: event SetTokenTransferFees(uint256 register, uint256 send) -func (_Gateway *GatewayFilterer) ParseSetTokenTransferFees(log types.Log) (*GatewaySetTokenTransferFees, error) { - event := new(GatewaySetTokenTransferFees) - if err := _Gateway.contract.UnpackLog(event, "SetTokenTransferFees", log); err != nil { +// Solidity: event TokenRegistrationSent(address token) +func (_Gateway *GatewayFilterer) ParseTokenRegistrationSent(log types.Log) (*GatewayTokenRegistrationSent, error) { + event := new(GatewayTokenRegistrationSent) + if err := _Gateway.contract.UnpackLog(event, "TokenRegistrationSent", log); err != nil { return nil, err } event.Raw = log return event, nil } -// GatewayTokenRegistrationSentIterator is returned from FilterTokenRegistrationSent and is used to iterate over the raw logs and unpacked data for TokenRegistrationSent events raised by the Gateway contract. -type GatewayTokenRegistrationSentIterator struct { - Event *GatewayTokenRegistrationSent // Event containing the contract specifics and raw log +// GatewayTokenSentIterator is returned from FilterTokenSent and is used to iterate over the raw logs and unpacked data for TokenSent events raised by the Gateway contract. +type GatewayTokenSentIterator struct { + Event *GatewayTokenSent // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1690,7 +1712,7 @@ type GatewayTokenRegistrationSentIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *GatewayTokenRegistrationSentIterator) Next() bool { +func (it *GatewayTokenSentIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1699,7 +1721,7 @@ func (it *GatewayTokenRegistrationSentIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(GatewayTokenRegistrationSent) + it.Event = new(GatewayTokenSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1714,7 +1736,7 @@ func (it *GatewayTokenRegistrationSentIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(GatewayTokenRegistrationSent) + it.Event = new(GatewayTokenSent) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1730,41 +1752,63 @@ func (it *GatewayTokenRegistrationSentIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *GatewayTokenRegistrationSentIterator) Error() error { +func (it *GatewayTokenSentIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *GatewayTokenRegistrationSentIterator) Close() error { +func (it *GatewayTokenSentIterator) Close() error { it.sub.Unsubscribe() return nil } -// GatewayTokenRegistrationSent represents a TokenRegistrationSent event raised by the Gateway contract. -type GatewayTokenRegistrationSent struct { - Token common.Address - Raw types.Log // Blockchain specific contextual infos +// GatewayTokenSent represents a TokenSent event raised by the Gateway contract. +type GatewayTokenSent struct { + Token common.Address + Sender common.Address + DestinationChain *big.Int + DestinationAddress []byte + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterTokenRegistrationSent is a free log retrieval operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. +// FilterTokenSent is a free log retrieval operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. // -// Solidity: event TokenRegistrationSent(address token) -func (_Gateway *GatewayFilterer) FilterTokenRegistrationSent(opts *bind.FilterOpts) (*GatewayTokenRegistrationSentIterator, error) { +// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) +func (_Gateway *GatewayFilterer) FilterTokenSent(opts *bind.FilterOpts, token []common.Address, sender []common.Address) (*GatewayTokenSentIterator, error) { - logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenRegistrationSent") + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenSent", tokenRule, senderRule) if err != nil { return nil, err } - return &GatewayTokenRegistrationSentIterator{contract: _Gateway.contract, event: "TokenRegistrationSent", logs: logs, sub: sub}, nil + return &GatewayTokenSentIterator{contract: _Gateway.contract, event: "TokenSent", logs: logs, sub: sub}, nil } -// WatchTokenRegistrationSent is a free log subscription operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. +// WatchTokenSent is a free log subscription operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. // -// Solidity: event TokenRegistrationSent(address token) -func (_Gateway *GatewayFilterer) WatchTokenRegistrationSent(opts *bind.WatchOpts, sink chan<- *GatewayTokenRegistrationSent) (event.Subscription, error) { +// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) +func (_Gateway *GatewayFilterer) WatchTokenSent(opts *bind.WatchOpts, sink chan<- *GatewayTokenSent, token []common.Address, sender []common.Address) (event.Subscription, error) { - logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenRegistrationSent") + var tokenRule []interface{} + for _, tokenItem := range token { + tokenRule = append(tokenRule, tokenItem) + } + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenSent", tokenRule, senderRule) if err != nil { return nil, err } @@ -1774,8 +1818,8 @@ func (_Gateway *GatewayFilterer) WatchTokenRegistrationSent(opts *bind.WatchOpts select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(GatewayTokenRegistrationSent) - if err := _Gateway.contract.UnpackLog(event, "TokenRegistrationSent", log); err != nil { + event := new(GatewayTokenSent) + if err := _Gateway.contract.UnpackLog(event, "TokenSent", log); err != nil { return err } event.Raw = log @@ -1796,21 +1840,21 @@ func (_Gateway *GatewayFilterer) WatchTokenRegistrationSent(opts *bind.WatchOpts }), nil } -// ParseTokenRegistrationSent is a log parse operation binding the contract event 0xf78bb28d4b1d7da699e5c0bc2be29c2b04b5aab6aacf6298fe5304f9db9c6d7e. +// ParseTokenSent is a log parse operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. // -// Solidity: event TokenRegistrationSent(address token) -func (_Gateway *GatewayFilterer) ParseTokenRegistrationSent(log types.Log) (*GatewayTokenRegistrationSent, error) { - event := new(GatewayTokenRegistrationSent) - if err := _Gateway.contract.UnpackLog(event, "TokenRegistrationSent", log); err != nil { +// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) +func (_Gateway *GatewayFilterer) ParseTokenSent(log types.Log) (*GatewayTokenSent, error) { + event := new(GatewayTokenSent) + if err := _Gateway.contract.UnpackLog(event, "TokenSent", log); err != nil { return nil, err } event.Raw = log return event, nil } -// GatewayTokenSentIterator is returned from FilterTokenSent and is used to iterate over the raw logs and unpacked data for TokenSent events raised by the Gateway contract. -type GatewayTokenSentIterator struct { - Event *GatewayTokenSent // Event containing the contract specifics and raw log +// GatewayTokenTransferFeesChangedIterator is returned from FilterTokenTransferFeesChanged and is used to iterate over the raw logs and unpacked data for TokenTransferFeesChanged events raised by the Gateway contract. +type GatewayTokenTransferFeesChangedIterator struct { + Event *GatewayTokenTransferFeesChanged // Event containing the contract specifics and raw log contract *bind.BoundContract // Generic contract to use for unpacking event data event string // Event name to use for unpacking event data @@ -1824,7 +1868,7 @@ type GatewayTokenSentIterator struct { // Next advances the iterator to the subsequent event, returning whether there // are any more events found. In case of a retrieval or parsing error, false is // returned and Error() can be queried for the exact failure. -func (it *GatewayTokenSentIterator) Next() bool { +func (it *GatewayTokenTransferFeesChangedIterator) Next() bool { // If the iterator failed, stop iterating if it.fail != nil { return false @@ -1833,7 +1877,7 @@ func (it *GatewayTokenSentIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(GatewayTokenSent) + it.Event = new(GatewayTokenTransferFeesChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1848,7 +1892,7 @@ func (it *GatewayTokenSentIterator) Next() bool { // Iterator still in progress, wait for either a data or an error event select { case log := <-it.logs: - it.Event = new(GatewayTokenSent) + it.Event = new(GatewayTokenTransferFeesChanged) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -1864,63 +1908,42 @@ func (it *GatewayTokenSentIterator) Next() bool { } // Error returns any retrieval or parsing error occurred during filtering. -func (it *GatewayTokenSentIterator) Error() error { +func (it *GatewayTokenTransferFeesChangedIterator) Error() error { return it.fail } // Close terminates the iteration process, releasing any pending underlying // resources. -func (it *GatewayTokenSentIterator) Close() error { +func (it *GatewayTokenTransferFeesChangedIterator) Close() error { it.sub.Unsubscribe() return nil } -// GatewayTokenSent represents a TokenSent event raised by the Gateway contract. -type GatewayTokenSent struct { - Token common.Address - Sender common.Address - DestinationChain *big.Int - DestinationAddress []byte - Amount *big.Int - Raw types.Log // Blockchain specific contextual infos +// GatewayTokenTransferFeesChanged represents a TokenTransferFeesChanged event raised by the Gateway contract. +type GatewayTokenTransferFeesChanged struct { + Register *big.Int + Send *big.Int + Raw types.Log // Blockchain specific contextual infos } -// FilterTokenSent is a free log retrieval operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. +// FilterTokenTransferFeesChanged is a free log retrieval operation binding the contract event 0xf8b9e90b8d22eedd745a43851ee14b456fc1ca0e7248defe1ee10a9619c897ed. // -// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) -func (_Gateway *GatewayFilterer) FilterTokenSent(opts *bind.FilterOpts, token []common.Address, sender []common.Address) (*GatewayTokenSentIterator, error) { +// Solidity: event TokenTransferFeesChanged(uint256 register, uint256 send) +func (_Gateway *GatewayFilterer) FilterTokenTransferFeesChanged(opts *bind.FilterOpts) (*GatewayTokenTransferFeesChangedIterator, error) { - var tokenRule []interface{} - for _, tokenItem := range token { - tokenRule = append(tokenRule, tokenItem) - } - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenSent", tokenRule, senderRule) + logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenTransferFeesChanged") if err != nil { return nil, err } - return &GatewayTokenSentIterator{contract: _Gateway.contract, event: "TokenSent", logs: logs, sub: sub}, nil + return &GatewayTokenTransferFeesChangedIterator{contract: _Gateway.contract, event: "TokenTransferFeesChanged", logs: logs, sub: sub}, nil } -// WatchTokenSent is a free log subscription operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. +// WatchTokenTransferFeesChanged is a free log subscription operation binding the contract event 0xf8b9e90b8d22eedd745a43851ee14b456fc1ca0e7248defe1ee10a9619c897ed. // -// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) -func (_Gateway *GatewayFilterer) WatchTokenSent(opts *bind.WatchOpts, sink chan<- *GatewayTokenSent, token []common.Address, sender []common.Address) (event.Subscription, error) { +// Solidity: event TokenTransferFeesChanged(uint256 register, uint256 send) +func (_Gateway *GatewayFilterer) WatchTokenTransferFeesChanged(opts *bind.WatchOpts, sink chan<- *GatewayTokenTransferFeesChanged) (event.Subscription, error) { - var tokenRule []interface{} - for _, tokenItem := range token { - tokenRule = append(tokenRule, tokenItem) - } - var senderRule []interface{} - for _, senderItem := range sender { - senderRule = append(senderRule, senderItem) - } - - logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenSent", tokenRule, senderRule) + logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenTransferFeesChanged") if err != nil { return nil, err } @@ -1930,8 +1953,8 @@ func (_Gateway *GatewayFilterer) WatchTokenSent(opts *bind.WatchOpts, sink chan< select { case log := <-logs: // New log arrived, parse the event and forward to the user - event := new(GatewayTokenSent) - if err := _Gateway.contract.UnpackLog(event, "TokenSent", log); err != nil { + event := new(GatewayTokenTransferFeesChanged) + if err := _Gateway.contract.UnpackLog(event, "TokenTransferFeesChanged", log); err != nil { return err } event.Raw = log @@ -1952,12 +1975,12 @@ func (_Gateway *GatewayFilterer) WatchTokenSent(opts *bind.WatchOpts, sink chan< }), nil } -// ParseTokenSent is a log parse operation binding the contract event 0x37ae4af9ee081dc143413d47231db2ed06e556615d5164b33c40142e1d4c46f5. +// ParseTokenTransferFeesChanged is a log parse operation binding the contract event 0xf8b9e90b8d22eedd745a43851ee14b456fc1ca0e7248defe1ee10a9619c897ed. // -// Solidity: event TokenSent(address indexed token, address indexed sender, uint256 destinationChain, bytes destinationAddress, uint128 amount) -func (_Gateway *GatewayFilterer) ParseTokenSent(log types.Log) (*GatewayTokenSent, error) { - event := new(GatewayTokenSent) - if err := _Gateway.contract.UnpackLog(event, "TokenSent", log); err != nil { +// Solidity: event TokenTransferFeesChanged(uint256 register, uint256 send) +func (_Gateway *GatewayFilterer) ParseTokenTransferFeesChanged(log types.Log) (*GatewayTokenTransferFeesChanged, error) { + event := new(GatewayTokenTransferFeesChanged) + if err := _Gateway.contract.UnpackLog(event, "TokenTransferFeesChanged", log); err != nil { return nil, err } event.Raw = log diff --git a/relayer/relays/execution/main.go b/relayer/relays/execution/main.go index 2519b88837..c39a7fa18e 100644 --- a/relayer/relays/execution/main.go +++ b/relayer/relays/execution/main.go @@ -255,7 +255,7 @@ func (r *Relay) findEvents( } func (r *Relay) findEventsWithFilter(opts *bind.FilterOpts, paraID uint32, start uint64) (bool, []*contracts.GatewayOutboundMessageAccepted, error) { - iter, err := r.gatewayContract.FilterOutboundMessageAccepted(opts, []*big.Int{big.NewInt(int64(paraID))}) + iter, err := r.gatewayContract.FilterOutboundMessageAccepted(opts, []*big.Int{big.NewInt(int64(paraID))}, [][32]byte{}) if err != nil { return false, nil, err } diff --git a/relayer/relays/parachain/types.go b/relayer/relays/parachain/types.go index 9bdff130e8..f002002236 100644 --- a/relayer/relays/parachain/types.go +++ b/relayer/relays/parachain/types.go @@ -90,6 +90,7 @@ type OutboundQueueMessage struct { MaxDispatchGas types.U128 MaxRefund types.U128 Reward types.U128 + ID types.Bytes32 } func (m OutboundQueueMessage) IntoInboundMessage() contracts.InboundMessage { @@ -101,6 +102,7 @@ func (m OutboundQueueMessage) IntoInboundMessage() contracts.InboundMessage { MaxDispatchGas: m.MaxDispatchGas.Int, MaxRefund: m.MaxRefund.Int, Reward: m.Reward.Int, + Id: m.ID, } } diff --git a/web/packages/test/scripts/configure-bridgehub.sh b/web/packages/test/scripts/configure-bridgehub.sh index 83fb369362..c43625d42c 100755 --- a/web/packages/test/scripts/configure-bridgehub.sh +++ b/web/packages/test/scripts/configure-bridgehub.sh @@ -74,7 +74,6 @@ configure_bridgehub() { wait_beacon_chain_ready config_beacon_checkpoint open_hrmp_channels - enable_gateway } if [ -z "${from_start_services:-}" ]; then diff --git a/web/packages/test/scripts/set-env.sh b/web/packages/test/scripts/set-env.sh index 74a703ced2..21585af512 100755 --- a/web/packages/test/scripts/set-env.sh +++ b/web/packages/test/scripts/set-env.sh @@ -77,6 +77,7 @@ export RANDAO_COMMIT_DELAY="${ETH_RANDAO_DELAY:-3}" export RANDAO_COMMIT_EXP="${ETH_RANDAO_EXP:-3}" export MINIMUM_REQUIRED_SIGNATURES="${MINIMUM_REQUIRED_SIGNATURES:-16}" +export REJECT_OUTBOUND_MESSAGES=false export DEFAULT_FEE="${ETH_DEFAULT_FEE:-1}" export CREATE_CALL_INDEX="${ETH_CREATE_CALL_INDEX:-0x3500}"