diff --git a/core/packages/contracts/src/AgentExecutor.sol b/core/packages/contracts/src/AgentExecutor.sol index 51fe29c9a7..ff6917d8eb 100644 --- a/core/packages/contracts/src/AgentExecutor.sol +++ b/core/packages/contracts/src/AgentExecutor.sol @@ -2,7 +2,7 @@ // SPDX-FileCopyrightText: 2023 Snowfork pragma solidity 0.8.20; -import {ParaID} from "./Types.sol"; +import {AgentExecuteCommand, ParaID} from "./Types.sol"; import {SubstrateTypes} from "./SubstrateTypes.sol"; import {IERC20} from "./interfaces/IERC20.sol"; @@ -12,11 +12,9 @@ contract AgentExecutor { using SafeTokenTransfer for IERC20; using SafeNativeTransfer for address payable; - bytes32 internal constant COMMAND_TRANSFER_TOKEN = keccak256("transferToken"); - function execute(address, bytes memory data) external { - (bytes32 command, bytes memory params) = abi.decode(data, (bytes32, bytes)); - if (command == COMMAND_TRANSFER_TOKEN) { + (AgentExecuteCommand command, bytes memory params) = abi.decode(data, (AgentExecuteCommand, bytes)); + if (command == AgentExecuteCommand.TransferToken) { (address token, address recipient, uint128 amount) = abi.decode(params, (address, address, uint128)); _transferToken(token, recipient, amount); } diff --git a/core/packages/contracts/src/Assets.sol b/core/packages/contracts/src/Assets.sol index 0347ab67d1..22239a99b2 100644 --- a/core/packages/contracts/src/Assets.sol +++ b/core/packages/contracts/src/Assets.sol @@ -48,9 +48,9 @@ library Assets { _transferToAgent(assetHubAgent, token, sender, amount); if (destinationChain == assetHubParaID) { - payload = SubstrateTypes.SendToken(assetHubAgent, token, destinationAddress, amount); + payload = SubstrateTypes.SendToken(address(this), token, destinationAddress, amount); } else { - payload = SubstrateTypes.SendToken(assetHubAgent, token, destinationChain, destinationAddress, amount); + payload = SubstrateTypes.SendToken(address(this), token, destinationChain, destinationAddress, amount); } extraFee = $.sendTokenFee; @@ -74,7 +74,7 @@ library Assets { _transferToAgent(assetHubAgent, token, sender, amount); - payload = SubstrateTypes.SendToken(assetHubAgent, token, destinationChain, destinationAddress, amount); + payload = SubstrateTypes.SendToken(address(this), token, destinationChain, destinationAddress, amount); extraFee = $.sendTokenFee; emit TokenSent(sender, token, destinationChain, abi.encodePacked(destinationAddress), amount); } @@ -93,7 +93,7 @@ library Assets { /// @dev Enqueues a create native token message to substrate. /// @param token The ERC20 token address. - function registerToken(address gateway, address token, bytes2 createTokenCallID) + function registerToken(address token, bytes2 createTokenCallID) external returns (bytes memory payload, uint256 extraFee) { @@ -103,7 +103,7 @@ library Assets { revert InvalidToken(); } - payload = SubstrateTypes.RegisterToken(gateway, token, createTokenCallID); + payload = SubstrateTypes.RegisterToken(address(this), token, createTokenCallID); extraFee = $.registerTokenFee; emit TokenRegistrationSent(token); diff --git a/core/packages/contracts/src/Gateway.sol b/core/packages/contracts/src/Gateway.sol index f91abcf2d6..de33bcaccb 100644 --- a/core/packages/contracts/src/Gateway.sol +++ b/core/packages/contracts/src/Gateway.sol @@ -384,10 +384,7 @@ contract Gateway is IGateway { // Register a token on AssetHub function registerToken(address token) external payable { - CoreStorage.Layout storage $ = CoreStorage.layout(); - address assetHubAgent = $.agents[ASSET_HUB_AGENT_ID]; - - (bytes memory payload, uint256 extraFee) = Assets.registerToken(assetHubAgent, token, CREATE_TOKEN_CALL_ID); + (bytes memory payload, uint256 extraFee) = Assets.registerToken(token, CREATE_TOKEN_CALL_ID); _submitOutbound(ASSET_HUB_PARA_ID, payload, extraFee); } diff --git a/core/packages/contracts/src/Types.sol b/core/packages/contracts/src/Types.sol index e8ef5497a9..7cc30824b7 100644 --- a/core/packages/contracts/src/Types.sol +++ b/core/packages/contracts/src/Types.sol @@ -55,3 +55,5 @@ enum Command { SetOperatingMode, TransferNativeFromAgent } + +enum AgentExecuteCommand {TransferToken} diff --git a/core/packages/contracts/test/Gateway.t.sol b/core/packages/contracts/test/Gateway.t.sol index 912a940f14..45b1130c0b 100644 --- a/core/packages/contracts/test/Gateway.t.sol +++ b/core/packages/contracts/test/Gateway.t.sol @@ -21,7 +21,7 @@ import {SubstrateTypes} from "./../src/SubstrateTypes.sol"; import {NativeTransferFailed} from "../src/utils/SafeTransfer.sol"; -import {InboundMessage, OperatingMode, ParaID, Config, Command} from "../src/Types.sol"; +import {AgentExecuteCommand, InboundMessage, OperatingMode, ParaID, Config, Command} from "../src/Types.sol"; import {WETH9} from "canonical-weth/WETH9.sol"; @@ -259,7 +259,7 @@ contract GatewayTest is Test { Gateway.AgentExecuteParams memory params = Gateway.AgentExecuteParams({ agentID: assetHubAgentID, - payload: abi.encode(keccak256("transferToken"), abi.encode(address(token), address(this), 1)) + payload: abi.encode(AgentExecuteCommand.TransferToken, abi.encode(address(token), address(this), 1)) }); GatewayMock(address(gateway)).agentExecutePublic(abi.encode(params)); diff --git a/core/packages/test/scripts/configure-bridgehub.sh b/core/packages/test/scripts/configure-bridgehub.sh index ba2412f6e7..6c7e0e2206 100755 --- a/core/packages/test/scripts/configure-bridgehub.sh +++ b/core/packages/test/scripts/configure-bridgehub.sh @@ -63,7 +63,7 @@ fund_accounts() transfer_balance $relaychain_ws_url "//Charlie" 1013 1000000000000000 $statemine_sovereign_account transfer_balance $relaychain_ws_url "//Charlie" 1013 1000000000000000 $beacon_relayer_pub_key transfer_balance $relaychain_ws_url "//Charlie" 1013 1000000000000000 $execution_relayer_pub_key - transfer_balance $relaychain_ws_url "//Charlie" 1000 1000000000000000 $registry_contract_sovereign_account + transfer_balance $relaychain_ws_url "//Charlie" 1000 1000000000000000 $gateway_contract_sovereign_account } configure_bridgehub() diff --git a/core/packages/test/scripts/set-env.sh b/core/packages/test/scripts/set-env.sh index 22c13850fb..56fc96a770 100755 --- a/core/packages/test/scripts/set-env.sh +++ b/core/packages/test/scripts/set-env.sh @@ -62,8 +62,8 @@ statemine_sovereign_account="${STATEMINE_SOVEREIGN_ACCOUNT:-0x70617261e803000000 beacon_relayer_pub_key="${BEACON_RELAYER_PUB_KEY:-0xc46e141b5083721ad5f5056ba1cded69dce4a65f027ed3362357605b1687986a}" # Execution relay account (//ExecutionRelay 5CFNWKMFPsw5Cs2Teo6Pvg7rWyjKiFfqPZs8U4MZXzMYFwXL in testnet) execution_relayer_pub_key="${EXECUTION_RELAYER_PUB_KEY:-0x08228efd065c58a043da95c8bf177659fc587643e71e7ed1534666177730196f}" -# Registry contract account (5EBBfBLm4uV4JMXXcKvZrPVmP9VyER9YSCgGdMUw5wBXnqag in testnet) -registry_contract_sovereign_account="${REGISTRY_CONTRACT_SOVEREIGN_ACCOUNT:-0x5d6987649e0dac78ddf852eb0f1b1d1bf2be9623d81cb16c17cfa145948bb6dc}" +# Gateway contract account (H8VBFC4LG91ByxMG6GwsCcAacjitnzGmGbqnvSEQFBywJEL in testnet) +gateway_contract_sovereign_account="${GATEWAY_CONTRACT_SOVEREIGN_ACCOUNT:-0xc9794dd8013efb2ad83f668845c62b373c16ad33971745731408058e4d0c6ff5}" # Config for deploying contracts @@ -80,11 +80,11 @@ export RANDAO_COMMIT_EXP="${ETH_RANDAO_EXP:-3}" export BRIDGE_HUB_PARAID=$bridgehub_para_id # TODO: update placeholder value -export BRIDGE_HUB_AGENT_ID="00000000000000000000000000000000000000000000000000000000000003f5" +export BRIDGE_HUB_AGENT_ID="0x05f0ced792884ed09997292bd95f8d0d1094bb3bded91ec3f2f08531624037d6" export ASSET_HUB_PARAID=$statemine_para_id # TODO: update placeholder value -export ASSET_HUB_AGENT_ID="00000000000000000000000000000000000000000000000000000000000003e8" +export ASSET_HUB_AGENT_ID="0x72456f48efed08af20e5b317abf8648ac66e86bb90a411d9b0b713f7364b75b4" export DEFAULT_FEE=1 export DEFAULT_REWARD=1 diff --git a/cumulus b/cumulus index c0d90e08c0..c6cf3c37f9 160000 --- a/cumulus +++ b/cumulus @@ -1 +1 @@ -Subproject commit c0d90e08c0b4e89cabefe983c09eaec0ad3a0e81 +Subproject commit c6cf3c37f94f5433ca3bfa2751083b9d1add1f35 diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 4c12853d98..b5afdccb5b 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -2646,6 +2646,7 @@ dependencies = [ "sp-std", "xcm", "xcm-builder", + "xcm-executor", ] [[package]] @@ -2820,6 +2821,7 @@ dependencies = [ "sp-runtime", "sp-std", "xcm", + "xcm-builder", "xcm-executor", ] diff --git a/parachain/pallets/control/Cargo.toml b/parachain/pallets/control/Cargo.toml index 1bbe4d7589..f3fa0511d2 100644 --- a/parachain/pallets/control/Cargo.toml +++ b/parachain/pallets/control/Cargo.toml @@ -29,6 +29,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "ma xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } xcm-builder = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } +xcm-executor = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } @@ -49,10 +50,12 @@ std = [ "sp-runtime/std", "xcm/std", "xcm-builder/std", + "xcm-executor/std", "ethabi/std" ] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", - "xcm-builder/runtime-benchmarks" + "xcm-builder/runtime-benchmarks", + "xcm-executor/runtime-benchmarks" ] try-runtime = ["frame-support/try-runtime"] diff --git a/parachain/pallets/control/src/lib.rs b/parachain/pallets/control/src/lib.rs index 45f0e77c61..fe0dcb9ab0 100644 --- a/parachain/pallets/control/src/lib.rs +++ b/parachain/pallets/control/src/lib.rs @@ -21,11 +21,10 @@ pub use weights::*; use snowbridge_core::{Command, OutboundMessage, OutboundQueue as OutboundQueueTrait, ParaId}; use sp_core::{H160, H256}; -use sp_io::hashing::blake2_256; use sp_runtime::traits::Hash; use sp_std::prelude::*; use xcm::prelude::*; -use xcm_builder::DescribeLocation; +use xcm_executor::traits::ConvertLocation; pub use pallet::*; @@ -47,7 +46,9 @@ pub mod pallet { type WeightInfo: WeightInfo; type MaxUpgradeDataSize: Get; type CreateAgentOrigin: EnsureOrigin; - type DescribeAgentLocation: DescribeLocation; + type AgentHashedDescription: ConvertLocation; + type UniversalLocation: Get; + type RelayLocation: Get; } #[pallet::event] @@ -107,13 +108,19 @@ pub mod pallet { #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::create_agent())] pub fn create_agent(origin: OriginFor) -> DispatchResult { - let agent_location: MultiLocation = T::CreateAgentOrigin::ensure_origin(origin)?; + let mut agent_location: MultiLocation = T::CreateAgentOrigin::ensure_origin(origin)?; + + // Normalize all locations relative to the relay unless its the relay itself. + let relay_location = T::RelayLocation::get(); + if agent_location != relay_location { + agent_location + .reanchor(&relay_location, T::UniversalLocation::get()) + .or(Err(Error::::LocationConversionFailed))?; + } - let agent_description = T::DescribeAgentLocation::describe_location(&agent_location) + let agent_id = T::AgentHashedDescription::convert_location(&agent_location) .ok_or(Error::::LocationConversionFailed)?; - let agent_id: H256 = blake2_256(&agent_description).into(); - if Agents::::contains_key(agent_id) { return Ok(()); } diff --git a/parachain/pallets/control/src/mock.rs b/parachain/pallets/control/src/mock.rs index 78af4a4d6a..f0026b9b85 100644 --- a/parachain/pallets/control/src/mock.rs +++ b/parachain/pallets/control/src/mock.rs @@ -8,7 +8,7 @@ use frame_support::{ }; #[cfg(feature = "runtime-benchmarks")] -use frame_benchmarking::whitelisted_caller; +use frame_benchmarking::v2::whitelisted_caller; use snowbridge_core::{OutboundMessage, OutboundMessageHash, ParaId, SubmitError}; use sp_core::H256; @@ -18,10 +18,7 @@ use sp_runtime::{ AccountId32, }; use xcm::prelude::*; -use xcm_builder::{ - DescribeAccountId32Terminal, DescribeAccountKey20Terminal, DescribeAllTerminal, DescribeFamily, - DescribePalletTerminal, -}; +use xcm_builder::{DescribeAllTerminal, DescribeFamily, HashedDescription}; type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -71,6 +68,10 @@ parameter_types! { pub const MaxUpgradeDataSize: u32 = 1024; pub const SS58Prefix: u8 = 42; pub const AnyNetwork: Option = None; + pub const RelayNetwork: Option = Some(NetworkId::Kusama); + pub const RelayLocation: MultiLocation = MultiLocation::parent(); + pub UniversalLocation: InteriorMultiLocation = + X2(GlobalConsensus(RelayNetwork::get().unwrap()), Parachain(1013)); } static ORIGIN_TABLE: &[([u8; 32], MultiLocation)] = &[ @@ -184,13 +185,6 @@ impl snowbridge_control::OutboundQueueTrait for MockOutboundQueue { } } -pub type DescribeAgentLocation = ( - DescribePalletTerminal, - DescribeAccountId32Terminal, - DescribeAccountKey20Terminal, - DescribeFamily, -); - impl snowbridge_control::Config for Test { type RuntimeEvent = RuntimeEvent; type OwnParaId = OwnParaId; @@ -198,7 +192,9 @@ impl snowbridge_control::Config for Test { type MessageHasher = BlakeTwo256; type MaxUpgradeDataSize = MaxUpgradeDataSize; type CreateAgentOrigin = EnsureOriginFromTable; - type DescribeAgentLocation = DescribeAgentLocation; + type UniversalLocation = UniversalLocation; + type RelayLocation = RelayLocation; + type AgentHashedDescription = HashedDescription>; type WeightInfo = (); } diff --git a/parachain/pallets/control/src/tests.rs b/parachain/pallets/control/src/tests.rs index 33deb990fd..fe8d8f6f4d 100644 --- a/parachain/pallets/control/src/tests.rs +++ b/parachain/pallets/control/src/tests.rs @@ -67,10 +67,10 @@ fn create_agent_with_local_account32_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([2; 32])); let expected_agent_id = - H256(hex!("9e85ef53611dcb973a337977a79217890f6c0d605de20ae4a828b1b9a95162c4")); + H256(hex!("57fc5659083f0cc883125ccb2c380a1397a3b08434586b8647cc44bcb3647d29")); let expected_multi_location = MultiLocation { parents: 0, - interior: X1(Junction::AccountId32 { network: None, id: [0; 32] }), + interior: X2(Parachain(1013), Junction::AccountId32 { network: None, id: [0; 32] }), }; assert!(!Agents::::contains_key(expected_agent_id)); @@ -89,10 +89,10 @@ fn create_agent_with_local_account20_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([3; 32])); let expected_agent_id = - H256(hex!("927a4def0d0bdd151dfa247a07e4036e12335ee71977426847be6e6e36e3c460")); + H256(hex!("fc29ec0899cf25874937d04b9b011760fa5dc5cf59af1448abefd389bba7bea2")); let expected_multi_location = MultiLocation { parents: 0, - interior: X1(AccountKey20 { network: None, key: [0; 20] }), + interior: X2(Parachain(1013), AccountKey20 { network: None, key: [0; 20] }), }; assert!(!Agents::::contains_key(expected_agent_id)); @@ -111,8 +111,9 @@ fn create_agent_with_local_pallet_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([4; 32])); let expected_agent_id = - H256(hex!("964c3b3f978db1febb282d675dcf2196eae3c28fd7c0885b738cee828262fcc2")); - let expected_multi_location = MultiLocation { parents: 0, interior: X1(PalletInstance(1)) }; + H256(hex!("ed40c69763094b73c0e3585eeb576fbcee6999123ff1f1beac1f05f5f4c9d945")); + let expected_multi_location = + MultiLocation { parents: 0, interior: X2(Parachain(1013), PalletInstance(1)) }; assert!(!Agents::::contains_key(expected_agent_id)); assert_eq!(EthereumControl::create_agent(origin), Ok(())); @@ -130,8 +131,8 @@ fn create_agent_with_sibling_chain_origin_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([5; 32])); let expected_agent_id = - H256(hex!("81c5ab2571199e3188135178f3c2c8e2d268be1313d029b30f534fa579b69b79")); - let expected_multi_location = MultiLocation { parents: 1, interior: X1(Parachain(1000)) }; + H256(hex!("72456f48efed08af20e5b317abf8648ac66e86bb90a411d9b0b713f7364b75b4")); + let expected_multi_location = MultiLocation { parents: 0, interior: X1(Parachain(1000)) }; assert!(!Agents::::contains_key(expected_agent_id)); assert_eq!(EthereumControl::create_agent(origin), Ok(())); @@ -149,9 +150,9 @@ fn create_agent_with_sibling_chain_account32_origin_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([7; 32])); let expected_agent_id = - H256(hex!("75ad585e231db5daf900819e8fb62af432610619d0d7a1156e5d78531b2c6493")); + H256(hex!("fb804b0b77f9c9d69a16d7a45de81225ab8da112e0eb8d2e0229c78086b8927a")); let expected_multi_location = MultiLocation { - parents: 1, + parents: 0, interior: X2(Parachain(1000), Junction::AccountId32 { network: None, id: [0; 32] }), }; @@ -171,9 +172,9 @@ fn create_agent_with_sibling_chain_account20_origin_yields_success() { new_test_ext().execute_with(|| { let origin = RuntimeOrigin::signed(AccountId32::new([8; 32])); let expected_agent_id = - H256(hex!("3a737a558137d674c5e9c49bd0e6389bf69e1825c8fd531af5534081016501ef")); + H256(hex!("74867486f141b159ba1e295bf616d740429269879d4291a12a65eaedbb4b502a")); let expected_multi_location = MultiLocation { - parents: 1, + parents: 0, interior: X2(Parachain(1000), AccountKey20 { network: None, key: [0; 20] }), }; diff --git a/parachain/pallets/inbound-queue/src/benchmarking/mod.rs b/parachain/pallets/inbound-queue/src/benchmarking/mod.rs index 669cca4cc8..5c6396948b 100644 --- a/parachain/pallets/inbound-queue/src/benchmarking/mod.rs +++ b/parachain/pallets/inbound-queue/src/benchmarking/mod.rs @@ -13,7 +13,6 @@ mod benchmarks { use super::*; use crate::benchmarking::fixtures::make_create_message; use hex_literal::hex; - use sp_runtime::print; const GATEWAY_ADDRESS: [u8; 20] = hex!["eda338e4dc46038493b885327842fd3e301cab39"]; @@ -34,7 +33,8 @@ mod benchmarks { let sovereign_account = dest_para.into_account_truncating(); let minimum_balance = T::Token::minimum_balance(); - let minimum_balance_u32: u32 = minimum_balance.try_into() + let minimum_balance_u32: u32 = minimum_balance + .try_into() .unwrap_or_else(|_| panic!("unable to cast minimum balance to u32")); // Make sure the sovereign balance is enough. This is a funny number, because diff --git a/parachain/primitives/core/src/lib.rs b/parachain/primitives/core/src/lib.rs index b0fb5420db..bc9cebbc4d 100644 --- a/parachain/primitives/core/src/lib.rs +++ b/parachain/primitives/core/src/lib.rs @@ -143,13 +143,21 @@ pub enum AgentExecuteCommand { } impl AgentExecuteCommand { + fn index(&self) -> u8 { + match self { + AgentExecuteCommand::TransferToken { .. } => 0, + } + } pub fn abi_encode(&self) -> Vec { match self { AgentExecuteCommand::TransferToken { token, recipient, amount } => { ethabi::encode(&vec![ - Token::Address(*token), - Token::Address(*token), - Token::Uint(U256::from(*amount)), + Token::Uint(self.index().into()), + Token::Bytes(ethabi::encode(&vec![ + Token::Address(*token), + Token::Address(*recipient), + Token::Uint(U256::from(*amount)), + ])), ]) }, } diff --git a/parachain/primitives/router/Cargo.toml b/parachain/primitives/router/Cargo.toml index 6d54a747df..2fe1bbf22e 100644 --- a/parachain/primitives/router/Cargo.toml +++ b/parachain/primitives/router/Cargo.toml @@ -17,6 +17,7 @@ sp-runtime = { git = "https://github.com/paritytech/substrate.git", branch = "ma sp-std = { git = "https://github.com/paritytech/substrate.git", branch = "master", default-features = false } xcm = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } +xcm-builder = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } xcm-executor = { git = "https://github.com/paritytech/polkadot.git", branch = "master", default-features = false } snowbridge-core = { path = "../../primitives/core", default-features = false } @@ -41,6 +42,7 @@ std = [ "sp-runtime/std", "sp-std/std", "xcm/std", + "xcm-builder/std", "xcm-executor/std", "snowbridge-core/std", "ethabi/std", diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index b68ead14e6..f610d31a75 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -243,13 +243,13 @@ mod tests { use xcm::v3::prelude::*; use xcm_executor::traits::ConvertLocation; - const CONTRACT_ADDRESS: [u8; 20] = hex!("D184c103F7acc340847eEE82a0B909E3358bc28d"); + const CONTRACT_ADDRESS: [u8; 20] = hex!("EDa338E4dC46038493b885327842fD3E301CaB39"); const NETWORK: NetworkId = Ethereum { chain_id: 15 }; const SS58_FORMAT: u16 = 2; const EXPECTED_SOVEREIGN_KEY: [u8; 32] = - hex!("5d6987649e0dac78ddf852eb0f1b1d1bf2be9623d81cb16c17cfa145948bb6dc"); + hex!("c9794dd8013efb2ad83f668845c62b373c16ad33971745731408058e4d0c6ff5"); const EXPECTED_SOVEREIGN_ADDRESS: &'static str = - "EgoKVgdhGVz41LyP2jckLrmXjnD35xitaX221ktZjQ2Xsxw"; + "H8VBFC4LG91ByxMG6GwsCcAacjitnzGmGbqnvSEQFBywJEL"; parameter_types! { pub EthereumNetwork: NetworkId = NETWORK; @@ -272,10 +272,11 @@ mod tests { .unwrap(); let address = frame_support::sp_runtime::AccountId32::new(account) .to_ss58check_with_version(SS58_FORMAT.into()); - assert_eq!(account, EXPECTED_SOVEREIGN_KEY); - assert_eq!(address, EXPECTED_SOVEREIGN_ADDRESS); println!("SS58: {}\nBytes: {:?}", address, account); + + assert_eq!(account, EXPECTED_SOVEREIGN_KEY); + assert_eq!(address, EXPECTED_SOVEREIGN_ADDRESS); } #[test] diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index fe46649302..1d4c0a6ea0 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -11,19 +11,26 @@ use snowbridge_core::{ use sp_core::{H160, H256}; use sp_std::{marker::PhantomData, prelude::*}; use xcm::v3::prelude::*; -use xcm_executor::traits::ExportXcm; +use xcm_builder::{DescribeAllTerminal, DescribeFamily, HashedDescription}; +use xcm_executor::traits::{ConvertLocation, ExportXcm}; -pub struct EthereumBlobExporter( - PhantomData<(UniversalLocation, BridgeLocation, OutboundQueue)>, -); +pub type AgentHashedDescription = HashedDescription>; -impl ExportXcm - for EthereumBlobExporter +pub struct EthereumBlobExporter< + UniversalLocation, + BridgeLocation, + OutboundQueue, + AgentHashedDescription, +>(PhantomData<(UniversalLocation, BridgeLocation, OutboundQueue, AgentHashedDescription)>); + +impl ExportXcm + for EthereumBlobExporter where UniversalLocation: Get, BridgeLocation: Get, OutboundQueue: OutboundQueueTrait, OutboundQueue::Ticket: Encode + Decode, + AgentHashedDescription: ConvertLocation, { type Ticket = Vec; @@ -107,20 +114,27 @@ where return Err(SendError::Unroutable); } + // local_sub is relative to the relaychain. No conversion needed. + let local_sub_location: MultiLocation = local_sub.into(); + let agent_id = match AgentHashedDescription::convert_location(&local_sub_location) { + Some(id) => id, + None => { + log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to not being able to create agent id. '{local_sub_location:?}'"); + return Err(SendError::Unroutable); + }, + }; + let outbound_message = OutboundMessage { origin: para_id.into(), - command: Command::AgentExecute { - agent_id: H256::zero(), - command: agent_execute_command, - }, + command: Command::AgentExecute { agent_id, command: agent_execute_command }, }; - let ticket = OutboundQueue::validate(&outbound_message).map_err(|_| { - log::error!(target: "xcm::ethereum_blob_exporter", "OutboundQueue validation of message failed"); + let ticket = OutboundQueue::validate(&outbound_message).map_err(|err| { + log::error!(target: "xcm::ethereum_blob_exporter", "OutboundQueue validation of message failed. {err:?}"); SendError::Unroutable })?; - log::info!(target: "xcm::ethereum_blob_exporter", "message validated"); + log::info!(target: "xcm::ethereum_blob_exporter", "message validated: location = {local_sub_location:?}, agent_id = '{agent_id:?}'"); // TODO: Fees if any currently returning empty multi assets as cost Ok((ticket.encode(), MultiAssets::default())) @@ -351,13 +365,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::NotApplicable)); } @@ -370,13 +383,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::MissingArgument)); } @@ -391,13 +403,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::NotApplicable)); } @@ -410,13 +421,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::MissingArgument)); } @@ -429,13 +439,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::Unroutable)); } @@ -452,6 +461,7 @@ mod tests { UniversalLocation, BridgedLocationWithoutGlobalConsensus, MockOkOutboundQueue, + AgentHashedDescription, >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::NotApplicable)); } @@ -469,6 +479,7 @@ mod tests { UniversalLocation, BridgedLocationWithoutRegistry, MockOkOutboundQueue, + AgentHashedDescription, >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::NotApplicable)); } @@ -483,13 +494,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::NotApplicable)); } @@ -503,13 +513,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::MissingArgument)); } @@ -523,13 +532,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::MissingArgument)); } @@ -543,13 +551,12 @@ mod tests { let mut message: Option> = None; let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::MissingArgument)); } @@ -599,13 +606,12 @@ mod tests { ); let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::Unroutable)); } @@ -627,13 +633,12 @@ mod tests { ); let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert_eq!(result, Err(SendError::Unroutable)); } @@ -681,23 +686,24 @@ mod tests { ); let result = - EthereumBlobExporter::::validate( - network, - channel, - &mut universal_source, - &mut destination, - &mut message, - ); + EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockOkOutboundQueue, + AgentHashedDescription, + >::validate(network, channel, &mut universal_source, &mut destination, &mut message); assert!(result.is_ok()); } #[test] fn exporter_deliver_with_submit_failure_yields_unroutable() { - let result = - EthereumBlobExporter::::deliver( - hex!("deadbeef").to_vec(), - ); + let result = EthereumBlobExporter::< + UniversalLocation, + BridgedLocation, + MockErrOutboundQueue, + AgentHashedDescription, + >::deliver(hex!("deadbeef").to_vec()); assert_eq!(result, Err(SendError::Transport("other transport error"))) } diff --git a/relayer/contracts/beefy_client.go b/relayer/contracts/beefy_client.go index 64fc8a1170..17a791c812 100644 --- a/relayer/contracts/beefy_client.go +++ b/relayer/contracts/beefy_client.go @@ -72,7 +72,7 @@ type BeefyClientValidatorSet struct { // BeefyClientMetaData contains all meta data concerning the BeefyClient contract. var BeefyClientMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_randaoCommitDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_randaoCommitExpiration\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidBitfield\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBitfieldLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRLeaf\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRLeafProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRRootLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTicket\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidValidatorProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoMMRRootInCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughClaims\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PrevRandaoAlreadyCaptured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PrevRandaoNotCaptured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProofSizeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TicketExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedCompactEncoding\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WaitPeriodNotOver\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"mmrRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockNumber\",\"type\":\"uint64\"}],\"name\":\"NewMMRRoot\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MMR_ROOT_ID\",\"outputs\":[{\"internalType\":\"bytes2\",\"name\":\"\",\"type\":\"bytes2\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitmentHash\",\"type\":\"bytes32\"}],\"name\":\"commitPrevRandao\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitmentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"}],\"name\":\"createFinalBitfield\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"bitsToSet\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"createInitialBitfield\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentValidatorSet\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"_initialBeefyBlock\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.ValidatorSet\",\"name\":\"_initialValidatorSet\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.ValidatorSet\",\"name\":\"_nextValidatorSet\",\"type\":\"tuple\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBeefyBlock\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestMMRRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextValidatorSet\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randaoCommitDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randaoCommitExpiration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof[]\",\"name\":\"proofs\",\"type\":\"tuple[]\"}],\"name\":\"submitFinal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof[]\",\"name\":\"proofs\",\"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\":\"bytes32\",\"name\":\"parachainHeadsRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.MMRLeaf\",\"name\":\"leaf\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"name\":\"submitFinalWithHandover\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"name\":\"submitInitial\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"name\":\"submitInitialWithHandover\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"tickets\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"blockNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"validatorSetLen\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"prevRandao\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"bitfieldHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"leafHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofOrder\",\"type\":\"uint256\"}],\"name\":\"verifyMMRLeafProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + ABI: "[{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_randaoCommitDelay\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"_randaoCommitExpiration\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"_initialBeefyBlock\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.ValidatorSet\",\"name\":\"_initialValidatorSet\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.ValidatorSet\",\"name\":\"_nextValidatorSet\",\"type\":\"tuple\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"InvalidBitfield\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidBitfieldLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRLeaf\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRLeafProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidMMRRootLength\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSignature\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidTicket\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidValidatorProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoMMRRootInCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughClaims\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PrevRandaoAlreadyCaptured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PrevRandaoNotCaptured\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ProofSizeExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StaleCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TicketExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"UnsupportedCompactEncoding\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"WaitPeriodNotOver\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"mmrRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"blockNumber\",\"type\":\"uint64\"}],\"name\":\"NewMMRRoot\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"MMR_ROOT_ID\",\"outputs\":[{\"internalType\":\"bytes2\",\"name\":\"\",\"type\":\"bytes2\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitmentHash\",\"type\":\"bytes32\"}],\"name\":\"commitPrevRandao\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"commitmentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"}],\"name\":\"createFinalBitfield\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[]\",\"name\":\"bitsToSet\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"length\",\"type\":\"uint256\"}],\"name\":\"createInitialBitfield\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"\",\"type\":\"uint256[]\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"currentValidatorSet\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestBeefyBlock\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"latestMMRRoot\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"nextValidatorSet\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"id\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"length\",\"type\":\"uint128\"},{\"internalType\":\"bytes32\",\"name\":\"root\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randaoCommitDelay\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"randaoCommitExpiration\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof[]\",\"name\":\"proofs\",\"type\":\"tuple[]\"}],\"name\":\"submitFinal\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof[]\",\"name\":\"proofs\",\"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\":\"bytes32\",\"name\":\"parachainHeadsRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structBeefyClient.MMRLeaf\",\"name\":\"leaf\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"name\":\"submitFinalWithHandover\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"name\":\"submitInitial\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint32\",\"name\":\"blockNumber\",\"type\":\"uint32\"},{\"internalType\":\"uint64\",\"name\":\"validatorSetID\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"bytes2\",\"name\":\"payloadID\",\"type\":\"bytes2\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structBeefyClient.PayloadItem[]\",\"name\":\"payload\",\"type\":\"tuple[]\"}],\"internalType\":\"structBeefyClient.Commitment\",\"name\":\"commitment\",\"type\":\"tuple\"},{\"internalType\":\"uint256[]\",\"name\":\"bitfield\",\"type\":\"uint256[]\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"v\",\"type\":\"uint8\"},{\"internalType\":\"bytes32\",\"name\":\"r\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"s\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"index\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structBeefyClient.ValidatorProof\",\"name\":\"proof\",\"type\":\"tuple\"}],\"name\":\"submitInitialWithHandover\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"tickets\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"account\",\"type\":\"address\"},{\"internalType\":\"uint64\",\"name\":\"blockNumber\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"validatorSetLen\",\"type\":\"uint32\"},{\"internalType\":\"uint256\",\"name\":\"prevRandao\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"bitfieldHash\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"leafHash\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"proofOrder\",\"type\":\"uint256\"}],\"name\":\"verifyMMRLeafProof\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", } // BeefyClientABI is the input ABI used to generate the binding from. @@ -650,27 +650,6 @@ func (_BeefyClient *BeefyClientTransactorSession) CommitPrevRandao(commitmentHas return _BeefyClient.Contract.CommitPrevRandao(&_BeefyClient.TransactOpts, commitmentHash) } -// Initialize is a paid mutator transaction binding the contract method 0xe104815d. -// -// Solidity: function initialize(uint64 _initialBeefyBlock, (uint128,uint128,bytes32) _initialValidatorSet, (uint128,uint128,bytes32) _nextValidatorSet) returns() -func (_BeefyClient *BeefyClientTransactor) Initialize(opts *bind.TransactOpts, _initialBeefyBlock uint64, _initialValidatorSet BeefyClientValidatorSet, _nextValidatorSet BeefyClientValidatorSet) (*types.Transaction, error) { - return _BeefyClient.contract.Transact(opts, "initialize", _initialBeefyBlock, _initialValidatorSet, _nextValidatorSet) -} - -// Initialize is a paid mutator transaction binding the contract method 0xe104815d. -// -// Solidity: function initialize(uint64 _initialBeefyBlock, (uint128,uint128,bytes32) _initialValidatorSet, (uint128,uint128,bytes32) _nextValidatorSet) returns() -func (_BeefyClient *BeefyClientSession) Initialize(_initialBeefyBlock uint64, _initialValidatorSet BeefyClientValidatorSet, _nextValidatorSet BeefyClientValidatorSet) (*types.Transaction, error) { - return _BeefyClient.Contract.Initialize(&_BeefyClient.TransactOpts, _initialBeefyBlock, _initialValidatorSet, _nextValidatorSet) -} - -// Initialize is a paid mutator transaction binding the contract method 0xe104815d. -// -// Solidity: function initialize(uint64 _initialBeefyBlock, (uint128,uint128,bytes32) _initialValidatorSet, (uint128,uint128,bytes32) _nextValidatorSet) returns() -func (_BeefyClient *BeefyClientTransactorSession) Initialize(_initialBeefyBlock uint64, _initialValidatorSet BeefyClientValidatorSet, _nextValidatorSet BeefyClientValidatorSet) (*types.Transaction, error) { - return _BeefyClient.Contract.Initialize(&_BeefyClient.TransactOpts, _initialBeefyBlock, _initialValidatorSet, _nextValidatorSet) -} - // SubmitFinal is a paid mutator transaction binding the contract method 0x719321f0. // // Solidity: function submitFinal((uint32,uint64,(bytes2,bytes)[]) commitment, uint256[] bitfield, (uint8,bytes32,bytes32,uint256,address,bytes32[])[] proofs) returns() diff --git a/relayer/contracts/gateway.go b/relayer/contracts/gateway.go index d5629e8751..f9e382bea2 100644 --- a/relayer/contracts/gateway.go +++ b/relayer/contracts/gateway.go @@ -81,7 +81,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\":\"dest\",\"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\":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\":\"channelFeeRewardOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"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\":\"registerNativeToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"recipient\",\"type\":\"bytes\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendNativeToken\",\"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\":\"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\"}]", + 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\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"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\":\"channelFeeRewardOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"},{\"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\":\"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\"}]", } // GatewayABI is the input ABI used to generate the binding from. @@ -418,46 +418,67 @@ func (_Gateway *GatewayCallerSession) OperatingMode() (uint8, error) { return _Gateway.Contract.OperatingMode(&_Gateway.CallOpts) } -// RegisterNativeToken is a paid mutator transaction binding the contract method 0x0830ce14. +// RegisterToken is a paid mutator transaction binding the contract method 0x09824a80. // -// Solidity: function registerNativeToken(address token) payable returns() -func (_Gateway *GatewayTransactor) RegisterNativeToken(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) { - return _Gateway.contract.Transact(opts, "registerNativeToken", token) +// Solidity: function registerToken(address token) payable returns() +func (_Gateway *GatewayTransactor) RegisterToken(opts *bind.TransactOpts, token common.Address) (*types.Transaction, error) { + return _Gateway.contract.Transact(opts, "registerToken", token) } -// RegisterNativeToken is a paid mutator transaction binding the contract method 0x0830ce14. +// RegisterToken is a paid mutator transaction binding the contract method 0x09824a80. // -// Solidity: function registerNativeToken(address token) payable returns() -func (_Gateway *GatewaySession) RegisterNativeToken(token common.Address) (*types.Transaction, error) { - return _Gateway.Contract.RegisterNativeToken(&_Gateway.TransactOpts, token) +// Solidity: function registerToken(address token) payable returns() +func (_Gateway *GatewaySession) RegisterToken(token common.Address) (*types.Transaction, error) { + return _Gateway.Contract.RegisterToken(&_Gateway.TransactOpts, token) } -// RegisterNativeToken is a paid mutator transaction binding the contract method 0x0830ce14. +// RegisterToken is a paid mutator transaction binding the contract method 0x09824a80. // -// Solidity: function registerNativeToken(address token) payable returns() -func (_Gateway *GatewayTransactorSession) RegisterNativeToken(token common.Address) (*types.Transaction, error) { - return _Gateway.Contract.RegisterNativeToken(&_Gateway.TransactOpts, token) +// Solidity: function registerToken(address token) payable returns() +func (_Gateway *GatewayTransactorSession) RegisterToken(token common.Address) (*types.Transaction, error) { + return _Gateway.Contract.RegisterToken(&_Gateway.TransactOpts, token) } -// SendNativeToken is a paid mutator transaction binding the contract method 0x1125e84b. +// SendToken is a paid mutator transaction binding the contract method 0x506acef5. // -// Solidity: function sendNativeToken(address token, bytes recipient, uint128 amount) payable returns() -func (_Gateway *GatewayTransactor) SendNativeToken(opts *bind.TransactOpts, token common.Address, recipient []byte, amount *big.Int) (*types.Transaction, error) { - return _Gateway.contract.Transact(opts, "sendNativeToken", token, recipient, amount) +// Solidity: function sendToken(address token, uint256 destinationChain, bytes32 destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewayTransactor) SendToken(opts *bind.TransactOpts, token common.Address, destinationChain *big.Int, destinationAddress [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Gateway.contract.Transact(opts, "sendToken", token, destinationChain, destinationAddress, amount) } -// SendNativeToken is a paid mutator transaction binding the contract method 0x1125e84b. +// SendToken is a paid mutator transaction binding the contract method 0x506acef5. // -// Solidity: function sendNativeToken(address token, bytes recipient, uint128 amount) payable returns() -func (_Gateway *GatewaySession) SendNativeToken(token common.Address, recipient []byte, amount *big.Int) (*types.Transaction, error) { - return _Gateway.Contract.SendNativeToken(&_Gateway.TransactOpts, token, recipient, amount) +// Solidity: function sendToken(address token, uint256 destinationChain, bytes32 destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewaySession) SendToken(token common.Address, destinationChain *big.Int, destinationAddress [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Gateway.Contract.SendToken(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) } -// SendNativeToken is a paid mutator transaction binding the contract method 0x1125e84b. +// SendToken is a paid mutator transaction binding the contract method 0x506acef5. // -// Solidity: function sendNativeToken(address token, bytes recipient, uint128 amount) payable returns() -func (_Gateway *GatewayTransactorSession) SendNativeToken(token common.Address, recipient []byte, amount *big.Int) (*types.Transaction, error) { - return _Gateway.Contract.SendNativeToken(&_Gateway.TransactOpts, token, recipient, amount) +// Solidity: function sendToken(address token, uint256 destinationChain, bytes32 destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewayTransactorSession) SendToken(token common.Address, destinationChain *big.Int, destinationAddress [32]byte, amount *big.Int) (*types.Transaction, error) { + return _Gateway.Contract.SendToken(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) +} + +// SendToken0 is a paid mutator transaction binding the contract method 0x960897bf. +// +// Solidity: function sendToken(address token, uint256 destinationChain, address destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewayTransactor) SendToken0(opts *bind.TransactOpts, token common.Address, destinationChain *big.Int, destinationAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _Gateway.contract.Transact(opts, "sendToken0", token, destinationChain, destinationAddress, amount) +} + +// SendToken0 is a paid mutator transaction binding the contract method 0x960897bf. +// +// Solidity: function sendToken(address token, uint256 destinationChain, address destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewaySession) SendToken0(token common.Address, destinationChain *big.Int, destinationAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _Gateway.Contract.SendToken0(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) +} + +// SendToken0 is a paid mutator transaction binding the contract method 0x960897bf. +// +// Solidity: function sendToken(address token, uint256 destinationChain, address destinationAddress, uint128 amount) payable returns() +func (_Gateway *GatewayTransactorSession) SendToken0(token common.Address, destinationChain *big.Int, destinationAddress common.Address, amount *big.Int) (*types.Transaction, error) { + return _Gateway.Contract.SendToken0(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) } // SubmitInbound is a paid mutator transaction binding the contract method 0x920ee69f. @@ -1407,23 +1428,23 @@ func (it *GatewayOutboundMessageAcceptedIterator) Close() error { // GatewayOutboundMessageAccepted represents a OutboundMessageAccepted event raised by the Gateway contract. type GatewayOutboundMessageAccepted struct { - Dest *big.Int - Nonce uint64 - Payload []byte - Raw types.Log // Blockchain specific contextual infos + Destination *big.Int + Nonce uint64 + Payload []byte + Raw types.Log // Blockchain specific contextual infos } // FilterOutboundMessageAccepted is a free log retrieval operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. // -// Solidity: event OutboundMessageAccepted(uint256 indexed dest, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, dest []*big.Int) (*GatewayOutboundMessageAcceptedIterator, error) { +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) +func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, destination []*big.Int) (*GatewayOutboundMessageAcceptedIterator, error) { - var destRule []interface{} - for _, destItem := range dest { - destRule = append(destRule, destItem) + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destRule) + logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destinationRule) if err != nil { return nil, err } @@ -1432,15 +1453,15 @@ func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.Filter // WatchOutboundMessageAccepted is a free log subscription operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. // -// Solidity: event OutboundMessageAccepted(uint256 indexed dest, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOpts, sink chan<- *GatewayOutboundMessageAccepted, dest []*big.Int) (event.Subscription, error) { +// 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) { - var destRule []interface{} - for _, destItem := range dest { - destRule = append(destRule, destItem) + var destinationRule []interface{} + for _, destinationItem := range destination { + destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destRule) + logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destinationRule) if err != nil { return nil, err } @@ -1474,7 +1495,7 @@ func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOp // ParseOutboundMessageAccepted is a log parse operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. // -// Solidity: event OutboundMessageAccepted(uint256 indexed dest, uint64 nonce, bytes payload) +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) func (_Gateway *GatewayFilterer) ParseOutboundMessageAccepted(log types.Log) (*GatewayOutboundMessageAccepted, error) { event := new(GatewayOutboundMessageAccepted) if err := _Gateway.contract.UnpackLog(event, "OutboundMessageAccepted", log); err != nil { @@ -1484,6 +1505,277 @@ func (_Gateway *GatewayFilterer) ParseOutboundMessageAccepted(log types.Log) (*G return event, nil } +// GatewayTokenRegisteredIterator is returned from FilterTokenRegistered and is used to iterate over the raw logs and unpacked data for TokenRegistered events raised by the Gateway contract. +type GatewayTokenRegisteredIterator struct { + Event *GatewayTokenRegistered // 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 + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// 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 *GatewayTokenRegisteredIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GatewayTokenRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GatewayTokenRegistered) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GatewayTokenRegisteredIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GatewayTokenRegisteredIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GatewayTokenRegistered represents a TokenRegistered event raised by the Gateway contract. +type GatewayTokenRegistered struct { + Token common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokenRegistered is a free log retrieval operation binding the contract event 0x158412daecdc1456d01568828bcdb18464cc7f1ce0215ddbc3f3cfede9d1e63d. +// +// Solidity: event TokenRegistered(address token) +func (_Gateway *GatewayFilterer) FilterTokenRegistered(opts *bind.FilterOpts) (*GatewayTokenRegisteredIterator, error) { + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenRegistered") + if err != nil { + return nil, err + } + return &GatewayTokenRegisteredIterator{contract: _Gateway.contract, event: "TokenRegistered", logs: logs, sub: sub}, nil +} + +// WatchTokenRegistered is a free log subscription operation binding the contract event 0x158412daecdc1456d01568828bcdb18464cc7f1ce0215ddbc3f3cfede9d1e63d. +// +// Solidity: event TokenRegistered(address token) +func (_Gateway *GatewayFilterer) WatchTokenRegistered(opts *bind.WatchOpts, sink chan<- *GatewayTokenRegistered) (event.Subscription, error) { + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenRegistered") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(GatewayTokenRegistered) + if err := _Gateway.contract.UnpackLog(event, "TokenRegistered", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTokenRegistered is a log parse operation binding the contract event 0x158412daecdc1456d01568828bcdb18464cc7f1ce0215ddbc3f3cfede9d1e63d. +// +// Solidity: event TokenRegistered(address token) +func (_Gateway *GatewayFilterer) ParseTokenRegistered(log types.Log) (*GatewayTokenRegistered, error) { + event := new(GatewayTokenRegistered) + if err := _Gateway.contract.UnpackLog(event, "TokenRegistered", 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 + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// 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 { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(GatewayTokenSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(GatewayTokenSent) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *GatewayTokenSentIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GatewayTokenSentIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GatewayTokenSent represents a TokenSent event raised by the Gateway contract. +type GatewayTokenSent struct { + Token common.Address + DestinationChain *big.Int + DestinationAddress []byte + Amount *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTokenSent is a free log retrieval operation binding the contract event 0xe1ae29e81ebd3cc6a74fb91c2d9f33e3d80313f1d106f2b24e62cac4bfc86d98. +// +// Solidity: event TokenSent(address token, uint256 destinationChain, bytes destinationAddress, uint128 amount) +func (_Gateway *GatewayFilterer) FilterTokenSent(opts *bind.FilterOpts) (*GatewayTokenSentIterator, error) { + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "TokenSent") + if err != nil { + return nil, err + } + return &GatewayTokenSentIterator{contract: _Gateway.contract, event: "TokenSent", logs: logs, sub: sub}, nil +} + +// WatchTokenSent is a free log subscription operation binding the contract event 0xe1ae29e81ebd3cc6a74fb91c2d9f33e3d80313f1d106f2b24e62cac4bfc86d98. +// +// Solidity: event TokenSent(address token, uint256 destinationChain, bytes destinationAddress, uint128 amount) +func (_Gateway *GatewayFilterer) WatchTokenSent(opts *bind.WatchOpts, sink chan<- *GatewayTokenSent) (event.Subscription, error) { + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "TokenSent") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + 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 { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTokenSent is a log parse operation binding the contract event 0xe1ae29e81ebd3cc6a74fb91c2d9f33e3d80313f1d106f2b24e62cac4bfc86d98. +// +// Solidity: event TokenSent(address token, 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 +} + // GatewayUpgradedIterator is returned from FilterUpgraded and is used to iterate over the raw logs and unpacked data for Upgraded events raised by the Gateway contract. type GatewayUpgradedIterator struct { Event *GatewayUpgraded // Event containing the contract specifics and raw log diff --git a/relayer/relays/execution/main.go b/relayer/relays/execution/main.go index 028195928e..2519b88837 100644 --- a/relayer/relays/execution/main.go +++ b/relayer/relays/execution/main.go @@ -138,7 +138,7 @@ func (r *Relay) Start(ctx context.Context, eg *errgroup.Group) error { "blockHash": ev.Raw.BlockHash.Hex(), "blockNumber": ev.Raw.BlockNumber, "txHash": ev.Raw.TxHash.Hex(), - "dest": ev.Dest, + "dest": ev.Destination, }) if ev.Nonce <= paraNonce { diff --git a/smoketest/tests/register_token.rs b/smoketest/tests/register_token.rs index 8101d36635..24c6ace8fc 100644 --- a/smoketest/tests/register_token.rs +++ b/smoketest/tests/register_token.rs @@ -52,7 +52,7 @@ async fn register_token() { let outbound_message_accepted_log = receipt.logs.last().unwrap(); // RLP-encode log and print it println!( - "receipt: {:?}", + "receipt: {:#?}", hex::encode(outbound_message_accepted_log.rlp_bytes()) ); diff --git a/smoketest/tests/send_tokens.rs b/smoketest/tests/send_tokens.rs index 3fc6b5b369..90a9b7d4ec 100644 --- a/smoketest/tests/send_tokens.rs +++ b/smoketest/tests/send_tokens.rs @@ -1,5 +1,5 @@ use hex_literal::hex; -use snowbridge_smoketest::contracts::{native_tokens, weth9}; +use snowbridge_smoketest::contracts::{i_gateway, weth9}; use std::{sync::Arc, time::Duration}; use ethers::{ @@ -10,17 +10,12 @@ use ethers::{ utils::parse_units, }; -use codec::Encode; - -use xcm::v3::{Junction, Junctions::X1, MultiLocation}; - // The deployment addresses of the following contracts are stable, unless we modify the order in // contracts are deployed in DeployScript.sol. const ETHEREUM_API: &str = "http://localhost:8545"; const ETHEREUM_KEY: &str = "0x5e002a1af63fd31f1c25258f3082dc889762664cb8f218d86da85dff8b07b342"; -const TOKEN_VAULT_CONTRACT: &str = "0xB8EA8cB425d85536b158d661da1ef0895Bb92F1D"; -const NATIVE_TOKENS_CONTRACT: &str = "0x8cF6147918A5CBb672703F879f385036f8793a24"; -const WETH_CONTRACT: &str = "0x440eDFFA1352B13227e8eE646f3Ea37456deC701"; +const GATEWAY_PROXY_CONTRACT: &str = "0xEDa338E4dC46038493b885327842fD3E301CaB39"; +const WETH_CONTRACT: &str = "0x87d1f7fdfEe7f651FaBc8bFCB6E086C278b77A7d"; // SS58: DE14BzQ1bDXWPKeLoAqdLAm1GpyAWaWF1knF74cEZeomTBM const FERDIE: [u8; 32] = hex!("1cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c"); @@ -40,16 +35,14 @@ async fn send_tokens() { let client = SignerMiddleware::new(provider.clone(), wallet.clone()); let client = Arc::new(client); - let native_tokens_addr = NATIVE_TOKENS_CONTRACT.parse::
().unwrap(); - let native_tokens = native_tokens::NativeTokens::new(native_tokens_addr, client.clone()); - - let token_vault_addr = TOKEN_VAULT_CONTRACT.parse::
().unwrap(); + let gateway_addr = GATEWAY_PROXY_CONTRACT.parse::
().unwrap(); + let gateway = i_gateway::IGateway::new(gateway_addr, client.clone()); let weth_addr = WETH_CONTRACT.parse::
().unwrap(); let weth = weth9::WETH9::new(weth_addr, client.clone()); // Mint WETH tokens - let value = parse_units("10", "ether").unwrap(); + let value = parse_units("1", "ether").unwrap(); let receipt = weth .deposit() .value(value) @@ -62,7 +55,7 @@ async fn send_tokens() { assert_eq!(receipt.status.unwrap().as_u64(), 1u64); // Approve token spend - weth.approve(token_vault_addr, value.into()) + weth.approve(gateway_addr, value.into()) .send() .await .unwrap() @@ -71,19 +64,10 @@ async fn send_tokens() { .unwrap(); assert_eq!(receipt.status.unwrap().as_u64(), 1u64); - let recipient = MultiLocation { - parents: 0, - interior: X1(Junction::AccountId32 { - network: None, - id: FERDIE, - }), - } - .encode(); - // Lock tokens into vault let value1: u128 = U256::from(value).low_u128(); - native_tokens - .lock(weth.address(), 0, recipient.into(), value1) + let receipt = gateway + .send_token(weth.address(), 1000.into(), FERDIE, value1) .value(1000) .send() .await