From 967b2f040943f97e70c1015b0c5aee758f360656 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Tue, 7 Nov 2023 16:09:14 +0200 Subject: [PATCH 01/20] Add support for message ids --- contracts/src/Assets.sol | 3 +- contracts/src/DeployScript.sol | 15 +- contracts/src/Gateway.sol | 13 +- contracts/src/Types.sol | 2 + contracts/src/interfaces/IGateway.sol | 20 +- contracts/test/Gateway.t.sol | 38 +-- parachain/Cargo.lock | 1 + parachain/pallets/control/src/lib.rs | 15 +- parachain/pallets/control/src/tests.rs | 8 +- .../pallets/ethereum-beacon-client/Cargo.toml | 2 +- parachain/pallets/inbound-queue/Cargo.toml | 6 +- .../pallets/inbound-queue/src/envelope.rs | 34 ++- parachain/pallets/inbound-queue/src/lib.rs | 60 ++--- parachain/pallets/inbound-queue/src/test.rs | 83 +------ .../outbound-queue/src/benchmarking.rs | 2 +- parachain/pallets/outbound-queue/src/lib.rs | 25 +- parachain/pallets/outbound-queue/src/mock.rs | 3 + .../outbound-queue/src/send_message_impl.rs | 38 +-- parachain/pallets/outbound-queue/src/types.rs | 4 + parachain/primitives/core/src/outbound.rs | 11 +- parachain/primitives/ethereum/Cargo.toml | 3 +- .../primitives/router/src/inbound/mod.rs | 1 + .../primitives/router/src/outbound/mod.rs | 46 ++-- polkadot-sdk | 2 +- relayer/contracts/gateway.go | 219 +++++++++++++++--- relayer/relays/execution/main.go | 2 +- relayer/relays/parachain/types.go | 2 + web/packages/test/scripts/set-env.sh | 2 + 28 files changed, 434 insertions(+), 226 deletions(-) diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index ed489fddca..3f04a3ba6e 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -9,7 +9,7 @@ import {SafeTokenTransferFrom} from "./utils/SafeTransfer.sol"; import {AssetsStorage} from "./storage/AssetsStorage.sol"; import {SubstrateTypes} from "./SubstrateTypes.sol"; -import {ParaID, Config} from "./Types.sol"; +import {ParaID, Config, Channel} from "./Types.sol"; import {Address} from "./utils/Address.sol"; /// @title Library for implementing Ethereum->Polkadot ERC20 transfers. @@ -71,6 +71,7 @@ library Assets { payload = SubstrateTypes.SendToken(address(this), token, destinationChain, destinationAddress, amount); extraFee = $.sendTokenFee; + emit IGateway.TokenSent(sender, token, destinationChain, abi.encodePacked(destinationAddress), amount); } diff --git a/contracts/src/DeployScript.sol b/contracts/src/DeployScript.sol index 2efddbe9f9..813a5c3388 100644 --- a/contracts/src/DeployScript.sol +++ b/contracts/src/DeployScript.sol @@ -12,7 +12,7 @@ import {Gateway} from "./Gateway.sol"; import {GatewayUpgradeMock} from "../test/mocks/GatewayUpgradeMock.sol"; import {Agent} from "./Agent.sol"; import {AgentExecutor} from "./AgentExecutor.sol"; -import {ParaID, Config} from "./Types.sol"; +import {ParaID, Config, OperatingMode} from "./Types.sol"; import {SafeNativeTransfer} from "./utils/SafeTransfer.sol"; import {stdJson} from "forge-std/StdJson.sol"; @@ -66,8 +66,19 @@ contract DeployScript is Script { assetHubAgentID ); + bool rejectOutboundMessages = vm.envBool("REJECT_OUTBOUND_MESSAGES"); + OperatingMode defaultOperatingMode; + if (rejectOutboundMessages) { + defaultOperatingMode = OperatingMode.RejectingOutboundMessages; + } else { + defaultOperatingMode = OperatingMode.Normal; + } + bytes memory initParams = abi.encode( - vm.envUint("DEFAULT_FEE"), vm.envUint("REGISTER_NATIVE_TOKEN_FEE"), vm.envUint("SEND_NATIVE_TOKEN_FEE") + defaultOperatingMode, + vm.envUint("DEFAULT_FEE"), + vm.envUint("REGISTER_NATIVE_TOKEN_FEE"), + vm.envUint("SEND_NATIVE_TOKEN_FEE") ); GatewayProxy gateway = new GatewayProxy(address(gatewayLogic), initParams); diff --git a/contracts/src/Gateway.sol b/contracts/src/Gateway.sol index 6609f4d8cc..6ac486fdfe 100644 --- a/contracts/src/Gateway.sol +++ b/contracts/src/Gateway.sol @@ -195,7 +195,7 @@ contract Gateway is IGateway, IInitializable { _transferNativeFromAgent(channel.agent, payable(msg.sender), amount); } - emit IGateway.InboundMessageDispatched(message.origin, message.nonce, success); + emit IGateway.InboundMessageDispatched(message.origin, message.nonce, message.id, success); } /** @@ -486,7 +486,10 @@ contract Gateway is IGateway, IInitializable { payable(msg.sender).safeNativeTransfer(msg.value - channel.fee - extraFee); } - emit IGateway.OutboundMessageAccepted(dest, channel.outboundNonce, payload); + // Generate a unique ID for this message + bytes32 messageID = keccak256(abi.encodePacked(dest, channel.outboundNonce)); + + emit IGateway.OutboundMessageAccepted(dest, channel.outboundNonce, messageID, payload); } /// @dev Outbound message can be disabled globally or on a per-channel basis. @@ -543,12 +546,12 @@ contract Gateway is IGateway, IInitializable { revert Unauthorized(); } - (uint256 defaultFee, uint256 registerTokenFee, uint256 sendTokenFee) = - abi.decode(data, (uint256, uint256, uint256)); + (OperatingMode defaultMode, uint256 defaultFee, uint256 registerTokenFee, uint256 sendTokenFee) = + abi.decode(data, (OperatingMode, uint256, uint256, uint256)); CoreStorage.Layout storage $ = CoreStorage.layout(); - $.mode = OperatingMode.RejectingOutboundMessages; + $.mode = defaultMode; $.defaultFee = defaultFee; // Initialize an agent & channel for BridgeHub diff --git a/contracts/src/Types.sol b/contracts/src/Types.sol index cb0fae8266..18c5f72ef7 100644 --- a/contracts/src/Types.sol +++ b/contracts/src/Types.sol @@ -45,6 +45,8 @@ struct InboundMessage { uint256 maxRefund; /// @dev The reward for message submission uint256 reward; + /// @dev ID for this message + bytes32 id; } enum OperatingMode { diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index c94b5fc261..aaf8e8ee1e 100644 --- a/contracts/src/interfaces/IGateway.sol +++ b/contracts/src/interfaces/IGateway.sol @@ -11,10 +11,13 @@ interface IGateway { */ // Emitted when inbound message has been dispatched - event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bool success); + event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bytes32 indexed messageID, bool success); // Emitted when an outbound message has been accepted for delivery to a Polkadot parachain - event OutboundMessageAccepted(ParaID indexed destination, uint64 nonce, bytes payload); + event OutboundMessageAccepted(ParaID indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); + + // Emitted when an dispatched inbound message or an accepted outbound message are associated with one or more topic IDs + event Topic(bytes32 topicID); // Emitted when an agent has been created for a consensus system on Polkadot event AgentCreated(bytes32 agentID, address agent); @@ -34,12 +37,6 @@ interface IGateway { // Emitted when funds are withdrawn from an agent event AgentFundsWithdrawn(bytes32 indexed agentID, address indexed recipient, uint256 amount); - /// @dev Emitted once the funds are locked and a message is successfully queued. - event TokenSent( - address indexed token, address indexed sender, ParaID destinationChain, bytes destinationAddress, uint128 amount - ); - event TokenRegistrationSent(address token); - /** * Getters */ @@ -66,6 +63,13 @@ interface IGateway { * Token Transfers */ + /// @dev Emitted once the funds are locked and a message is successfully queued. + event TokenSent( + address indexed token, address indexed sender, ParaID destinationChain, bytes destinationAddress, uint128 amount + ); + + event TokenRegistrationSent(address token); + /// @dev Send a message to the AssetHub parachain to register a new fungible asset /// in the `ForeignAssets` pallet. function registerToken(address token) external payable; diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index ba49b37244..c7c622a43f 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -66,6 +66,7 @@ contract GatewayTest is Test { uint256 public maxDispatchGas = 500_000; uint256 public maxRefund = 1 ether; uint256 public reward = 1 ether; + bytes32 public messageID = keccak256("cabbage"); uint256 public baseFee = 1 ether; uint256 public registerNativeTokenFee = 1 ether; @@ -84,6 +85,7 @@ contract GatewayTest is Test { gateway = new GatewayProxy( address(gatewayLogic), abi.encode( + OperatingMode.Normal, baseFee, registerNativeTokenFee, sendNativeTokenFee @@ -156,11 +158,11 @@ contract GatewayTest is Test { // Expect the gateway to emit `InboundMessageDispatched` vm.expectEmit(true, false, false, false); - emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, true); + emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, messageID, true); hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -173,7 +175,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -182,7 +184,7 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.InvalidNonce.selector); hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -194,7 +196,9 @@ contract GatewayTest is Test { vm.expectRevert(Gateway.ChannelDoesNotExist.selector); hoax(relayer); IGateway(address(gateway)).submitInbound( - InboundMessage(ParaID.wrap(42), 1, command, "", maxDispatchGas, maxRefund, reward), proof, makeMockProof() + InboundMessage(ParaID.wrap(42), 1, command, "", maxDispatchGas, maxRefund, reward, messageID), + proof, + makeMockProof() ); } @@ -208,7 +212,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -231,7 +235,7 @@ contract GatewayTest is Test { uint256 startGas = gasleft(); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -257,7 +261,7 @@ contract GatewayTest is Test { hoax(relayer, 1 ether); IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward), + InboundMessage(bridgeHubParaID, 1, command, params, maxDispatchGas, maxRefund, reward, messageID), proof, makeMockProof() ); @@ -535,7 +539,7 @@ contract GatewayTest is Test { emit TokenRegistrationSent(address(token)); vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, SubstrateTypes.RegisterToken(address(token))); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).registerToken{value: 2 ether}(address(token)); } @@ -545,7 +549,7 @@ contract GatewayTest is Test { emit IGateway.TokenRegistrationSent(address(token)); vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, SubstrateTypes.RegisterToken(address(token))); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); uint256 totalFee = baseFee + registerNativeTokenFee; uint256 balanceBefore = address(this).balance; @@ -571,9 +575,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted( - assetHubParaID, 1, SubstrateTypes.SendToken(address(token), destPara, destAddress, 1) - ); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -591,9 +593,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted( - assetHubParaID, 1, SubstrateTypes.SendToken(address(token), destAddress, 1) - ); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -611,7 +611,7 @@ contract GatewayTest is Test { // Expect the gateway to emit `OutboundMessageAccepted` vm.expectEmit(true, false, false, false); - emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, hex""); + emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); IGateway(address(gateway)).sendToken{value: 2 ether}(address(token), destPara, destAddress, 1); } @@ -743,10 +743,10 @@ contract GatewayTest is Test { vm.expectEmit(true, false, false, true); // Expect dispatch result as false for `OutOfGas` - emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, false); + emit IGateway.InboundMessageDispatched(bridgeHubParaID, 1, messageID, false); // maxDispatchGas as 1 for `create_agent` is definitely not enough IGateway(address(gateway)).submitInbound( - InboundMessage(bridgeHubParaID, 1, command, params, 1, maxRefund, reward), proof, makeMockProof() + InboundMessage(bridgeHubParaID, 1, command, params, 1, maxRefund, reward, messageID), proof, makeMockProof() ); } } diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 8732841b3f..c26c95b7e2 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -3241,6 +3241,7 @@ dependencies = [ "frame-support", "frame-system", "hex-literal", + "log", "pallet-balances", "parity-scale-codec", "rlp", diff --git a/parachain/pallets/control/src/lib.rs b/parachain/pallets/control/src/lib.rs index c1946d8cc8..627ec9ac23 100644 --- a/parachain/pallets/control/src/lib.rs +++ b/parachain/pallets/control/src/lib.rs @@ -200,6 +200,10 @@ pub mod pallet { #[pallet::getter(fn channels)] pub type Channels = StorageMap<_, Twox64Concat, ParaId, (), OptionQuery>; + /// Generator for a unique message ID + #[pallet::storage] + pub type NextMessageId = StorageValue<_, u64, ValueQuery>; + #[pallet::call] impl Pallet { /// Sends command to the Gateway contract to upgrade itself with a new implementation @@ -429,7 +433,7 @@ pub mod pallet { impl Pallet { /// Send `command` to the Gateway on the channel identified by `origin`. fn send(origin: ParaId, command: Command, pays_fee: PaysFee) -> DispatchResult { - let message = Message { origin, command }; + let message = Message { id: Self::alloc_message_id(), origin, command }; let (ticket, fee) = T::OutboundQueue::validate(&message).map_err(|err| Error::::Send(err))?; @@ -473,5 +477,14 @@ pub mod pallet { }); Ok(()) } + + // Allocate a unique id for a message. Used in the implementation of SendMessage,. + pub(crate) fn alloc_message_id() -> H256 { + NextMessageId::::mutate(|next_message_id| { + *next_message_id = next_message_id.saturating_add(1) + }); + let next_message_id = NextMessageId::::get(); + sp_io::hashing::blake2_256(&(next_message_id.encode())).into() + } } } diff --git a/parachain/pallets/control/src/tests.rs b/parachain/pallets/control/src/tests.rs index 92548f9ee9..ba8b77f995 100644 --- a/parachain/pallets/control/src/tests.rs +++ b/parachain/pallets/control/src/tests.rs @@ -520,8 +520,11 @@ fn charge_fee_for_create_agent() { assert_ok!(EthereumControl::create_agent(origin.clone())); // assert sovereign_balance decreased by (fee.base_fee + fee.delivery_fee) - let message = - Message { origin: para_id.into(), command: Command::CreateAgent { agent_id } }; + let message = Message { + id: H256::zero(), + origin: para_id.into(), + command: Command::CreateAgent { agent_id }, + }; let (_, fee) = OutboundQueue::validate(&message).unwrap(); let sovereign_balance = Balances::balance(&sovereign_account); assert_eq!(sovereign_balance + fee.local + fee.remote, InitialFunding::get()); @@ -555,6 +558,7 @@ fn charge_fee_for_transfer_native_from_agent() { let sovereign_balance_before = Balances::balance(&sovereign_account); assert_ok!(EthereumControl::transfer_native_from_agent(origin.clone(), recipient, amount)); let message = Message { + id: H256::zero(), origin: para_id.into(), command: Command::TransferNativeFromAgent { agent_id, recipient, amount }, }; diff --git a/parachain/pallets/ethereum-beacon-client/Cargo.toml b/parachain/pallets/ethereum-beacon-client/Cargo.toml index e3a20829cb..f4318a293c 100644 --- a/parachain/pallets/ethereum-beacon-client/Cargo.toml +++ b/parachain/pallets/ethereum-beacon-client/Cargo.toml @@ -18,7 +18,7 @@ scale-info = { version = "2.9.0", default-features = false, features = [ "derive ssz_rs = { version="0.9.0", default-features = false } ssz_rs_derive = { version="0.9.0", default-features = false } byte-slice-cast = { version = "1.2.1", default-features = false } -rlp = { version = "0.5", default-features = false } +rlp = { version = "0.5.2", default-features = false } hex-literal = { version = "0.4.1", optional = true } log = { version = "0.4.20", default-features = false } diff --git a/parachain/pallets/inbound-queue/Cargo.toml b/parachain/pallets/inbound-queue/Cargo.toml index 0f3da50660..226b127e42 100644 --- a/parachain/pallets/inbound-queue/Cargo.toml +++ b/parachain/pallets/inbound-queue/Cargo.toml @@ -14,7 +14,8 @@ serde = { version = "1.0.188", optional = true } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = [ "derive" ] } scale-info = { version = "2.9.0", default-features = false, features = [ "derive" ] } hex-literal = { version = "0.4.1", optional = true } -rlp = { version = "0.5", default-features = false, optional = true } +rlp = { version = "0.5.2", default-features = false, optional = true } +log = { version = "0.4.20", default-features = false } frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../polkadot-sdk/substrate/frame/support", default-features = false } @@ -41,12 +42,13 @@ snowbridge-beacon-primitives = { path = "../../primitives/beacon" } snowbridge-ethereum-beacon-client = { path = "../../pallets/ethereum-beacon-client" } hex-literal = { version = "0.4.1" } -rlp = { version = "0.5" } +rlp = { version = "0.5.2" } [features] default = ["std"] std = [ "serde", + "log/std", "codec/std", "scale-info/std", "frame-support/std", diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index 3ce9dfd71d..0462faa2f0 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -4,15 +4,16 @@ use ethabi::{Event, Param, ParamKind, Token}; use snowbridge_core::ParaId; use snowbridge_ethereum::{log::Log, H160}; -use sp_core::RuntimeDebug; +use sp_core::{RuntimeDebug, H256}; use sp_std::{convert::TryFrom, prelude::*}; // Used to decode an OutboundMessageAccepted log into an [`Envelope`]. static EVENT_ABI: &Event = &Event { - signature: "OutboundMessageAccepted(uint256,uint64,bytes)", + signature: "OutboundMessageAccepted(uint256,uint64,bytes32,bytes)", inputs: &[ Param { kind: ParamKind::Uint(256), indexed: true }, Param { kind: ParamKind::Uint(64), indexed: false }, + Param { kind: ParamKind::FixedBytes(32), indexed: true }, Param { kind: ParamKind::Bytes, indexed: false }, ], anonymous: false, @@ -27,10 +28,14 @@ pub struct Envelope { pub dest: ParaId, /// A nonce for enforcing replay protection and ordering. pub nonce: u64, + /// An id for tracing the message on its route (has no role in bridge consensus) + pub message_id: H256, /// The inner payload generated from the source application. pub payload: Vec, } +use log; + #[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug)] pub struct EnvelopeDecodeError; @@ -38,8 +43,12 @@ impl TryFrom for Envelope { type Error = EnvelopeDecodeError; fn try_from(log: Log) -> Result { + log::info!(target: "snowbridge-inbound-queue", "FOO -2"); + let tokens = EVENT_ABI.decode(log.topics, log.data).map_err(|_| EnvelopeDecodeError)?; + log::info!(target: "snowbridge-inbound-queue", "FOO -1"); + let mut iter = tokens.into_iter(); let dest = match iter.next().ok_or(EnvelopeDecodeError)? { @@ -47,16 +56,35 @@ impl TryFrom for Envelope { _ => return Err(EnvelopeDecodeError), }; + log::info!(target: "snowbridge-inbound-queue", "FOO 0"); + let nonce = match iter.next().ok_or(EnvelopeDecodeError)? { Token::Uint(nonce) => nonce.low_u64(), _ => return Err(EnvelopeDecodeError), }; + log::info!(target: "snowbridge-inbound-queue", "FOO 1"); + + let message_id = match iter.next().ok_or(EnvelopeDecodeError)? { + Token::FixedBytes(message_id) => { + log::info!(target: "snowbridge-inbound-queue", "FOO 2"); + let message_id: [u8; 32] = + message_id.try_into().map_err(|_| EnvelopeDecodeError)?; + log::info!(target: "snowbridge-inbound-queue", "FOO 3"); + H256::from(&message_id) + }, + _ => return Err(EnvelopeDecodeError), + }; + + log::info!(target: "snowbridge-inbound-queue", "FOO 4"); + let payload = match iter.next().ok_or(EnvelopeDecodeError)? { Token::Bytes(payload) => payload, _ => return Err(EnvelopeDecodeError), }; - Ok(Self { gateway: log.address, dest, nonce, payload }) + log::info!(target: "snowbridge-inbound-queue", "FOO 5"); + + Ok(Self { gateway: log.address, dest, nonce, message_id, payload }) } } diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index a48b8ff4ce..a2d47f9c1e 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -29,9 +29,7 @@ mod envelope; mod benchmarking; #[cfg(feature = "runtime-benchmarks")] -use snowbridge_beacon_primitives::CompactExecutionHeader; -#[cfg(feature = "runtime-benchmarks")] -use snowbridge_ethereum::H256; +use {snowbridge_beacon_primitives::CompactExecutionHeader, sp_core::H256}; pub mod weights; @@ -39,20 +37,17 @@ pub mod weights; mod test; use codec::{Decode, DecodeAll, Encode}; +use envelope::Envelope; use frame_support::{ - traits::fungible::{Inspect, Mutate}, + traits::{ + fungible::{Inspect, Mutate}, + tokens::Preservation, + }, + weights::WeightToFee, PalletError, }; use frame_system::ensure_signed; use scale_info::TypeInfo; -use sp_core::H160; -use sp_std::convert::TryFrom; -use xcm::v3::{ - send_xcm, Junction::*, Junctions::*, MultiLocation, SendError as XcmpSendError, SendXcm, - XcmHash, -}; - -use envelope::Envelope; use snowbridge_core::{ inbound::{Message, Verifier}, sibling_sovereign_account, BasicOperatingMode, ParaId, @@ -61,12 +56,14 @@ use snowbridge_router_primitives::{ inbound, inbound::{ConvertMessage, ConvertMessageError}, }; - +use sp_core::H160; use sp_runtime::traits::Saturating; - -use frame_support::{traits::tokens::Preservation, weights::WeightToFee}; - +use sp_std::convert::TryFrom; pub use weights::WeightInfo; +use xcm::v3::{ + send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, + SendError as XcmpSendError, SendXcm, +}; type BalanceOf = <::Token as Inspect<::AccountId>>::Balance; @@ -136,8 +133,8 @@ pub mod pallet { dest: ParaId, /// The message nonce nonce: u64, - /// XCM hash - xcm_hash: XcmHash, + /// ID of the XCM message which was forwarded to the final destination parachain + message_id: [u8; 32], }, /// Set OperatingMode OperatingModeChanged { mode: BasicOperatingMode }, @@ -210,11 +207,16 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Self::operating_mode().is_halted(), Error::::Halted); + log::info!(target: "snowbridge-inbound-queue", "WOOP"); + // submit message to verifier for verification - let log = T::Verifier::verify(&message)?; + let logf = T::Verifier::verify(&message)?; + + log::info!(target: "snowbridge-inbound-queue", "BAR: {:?} {:?}", logf.data.len(), logf.topics.len()); + log::info!(target: "snowbridge-inbound-queue", "BOOZ: {:?}", logf.topics.get(0).unwrap()); // Decode log into an Envelope - let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope)?; + let envelope = Envelope::try_from(logf).map_err(|_| Error::::InvalidEnvelope)?; // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == envelope.gateway, Error::::InvalidGateway,); @@ -244,20 +246,24 @@ pub mod pallet { )?; // Decode message into XCM - let xcm = match inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()) { - Ok(message) => T::MessageConverter::convert(message) - .map_err(|e| Error::::ConvertMessage(e))?, - Err(_) => return Err(Error::::InvalidPayload.into()), - }; + let mut xcm = + match inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()) { + Ok(message) => T::MessageConverter::convert(message) + .map_err(|e| Error::::ConvertMessage(e))?, + Err(_) => return Err(Error::::InvalidPayload.into()), + }; + + // Append the message id as an XCM topic + xcm.inner_mut().extend(vec![SetTopic(envelope.message_id.into())]); // Attempt to send XCM to a dest parachain let dest = MultiLocation { parents: 1, interior: X1(Parachain(envelope.dest.into())) }; - let (xcm_hash, _) = send_xcm::(dest, xcm).map_err(Error::::from)?; + let (message_id, _) = send_xcm::(dest, xcm).map_err(Error::::from)?; Self::deposit_event(Event::MessageReceived { dest: envelope.dest, nonce: envelope.nonce, - xcm_hash, + message_id, }); Ok(()) diff --git a/parachain/pallets/inbound-queue/src/test.rs b/parachain/pallets/inbound-queue/src/test.rs index 59db735ffa..c34c1c8fe3 100644 --- a/parachain/pallets/inbound-queue/src/test.rs +++ b/parachain/pallets/inbound-queue/src/test.rs @@ -238,36 +238,29 @@ fn parse_dest(message: Message) -> ParaId { } // dest para is 1000 -const OUTBOUND_QUEUE_EVENT_LOG: [u8; 221] = hex!( +const OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); // dest para is 1001 -const OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST: [u8; 221] = hex!( +const OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST: [u8; 254] = hex!( " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e9b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e9a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); -// gateway in message does not match configured gateway in runtime -const BAD_OUTBOUND_QUEUE_EVENT_LOG: [u8; 221] = hex!( +// gateway in message does not match configured gateway in runtimeå +const BAD_OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( " - f8db940000000000000000000000000000000000000000f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 - " -); - -// invalid payload with unsupported version -const BAD_OUTBOUND_QUEUE_LOG_UNSUPPORTED_VERSION: [u8; 221] = hex!( - " - f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e010f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 + f8fc940000000000000000000000000000000000000000f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 " ); const XCM_HASH: [u8; 32] = [ - 186, 27, 67, 39, 117, 164, 224, 191, 202, 232, 218, 108, 34, 65, 36, 199, 247, 19, 150, 198, - 182, 180, 39, 112, 150, 64, 84, 15, 174, 213, 183, 207, + 201, 101, 244, 67, 153, 61, 253, 203, 92, 23, 197, 172, 112, 209, 53, 248, 118, 25, 253, 110, + 168, 201, 60, 156, 227, 26, 55, 145, 5, 177, 78, 189, ]; const ASSET_HUB_PARAID: u32 = 1000u32; const TEMPLATE_PARAID: u32 = 1001u32; @@ -296,7 +289,7 @@ fn test_submit_happy_path() { expect_events(vec![InboundQueueEvent::MessageReceived { dest: ASSET_HUB_PARAID.into(), nonce: 1, - xcm_hash: XCM_HASH, + message_id: XCM_HASH, } .into()]); }); @@ -414,62 +407,6 @@ fn test_submit_no_funds_to_reward_relayers() { }); } -#[test] -fn test_convert_xcm_message() { - new_tester().execute_with(|| { - // Submit message - let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), - proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), - }, - }; - let log = ::Verifier::verify(&message).unwrap(); - - // Decode log into an Envelope - let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope).unwrap(); - - let message = - inbound::VersionedMessage::decode_all(&mut envelope.payload.as_ref()).unwrap(); - - let xcm = ::MessageConverter::convert(message).unwrap(); - - println!("xcm: {:?}", xcm); - - let hash = xcm.using_encoded(sp_io::hashing::blake2_256); - - assert_eq!(hash, XCM_HASH); - }) -} - -#[test] -fn test_submit_with_invalid_payload_unsupported_version() { - new_tester().execute_with(|| { - let relayer: AccountId = Keyring::Bob.into(); - let origin = RuntimeOrigin::signed(relayer); - - // Deposit funds into sovereign account of Asset Hub (Statemint) - let sovereign_account = sibling_sovereign_account::(ASSET_HUB_PARAID.into()); - let _ = Balances::mint_into(&sovereign_account, 10000); - - // Submit message - let message = Message { - data: BAD_OUTBOUND_QUEUE_LOG_UNSUPPORTED_VERSION.into(), - proof: Proof { - block_hash: Default::default(), - tx_index: Default::default(), - data: Default::default(), - }, - }; - assert_noop!( - InboundQueue::submit(origin.clone(), message.clone()), - Error::::InvalidPayload - ); - }); -} - #[test] fn test_set_operating_mode() { new_tester().execute_with(|| { diff --git a/parachain/pallets/outbound-queue/src/benchmarking.rs b/parachain/pallets/outbound-queue/src/benchmarking.rs index 9fead12bfc..921507425f 100644 --- a/parachain/pallets/outbound-queue/src/benchmarking.rs +++ b/parachain/pallets/outbound-queue/src/benchmarking.rs @@ -21,7 +21,7 @@ mod benchmarks { #[benchmark] fn do_process_message() -> Result<(), BenchmarkError> { let enqueued_message = QueuedMessage { - id: H256::zero().into(), + id: H256::zero(), origin: 1000.into(), command: Command::Upgrade { impl_address: H160::zero(), diff --git a/parachain/pallets/outbound-queue/src/lib.rs b/parachain/pallets/outbound-queue/src/lib.rs index 283e13d9c6..2b9fb6b8ff 100644 --- a/parachain/pallets/outbound-queue/src/lib.rs +++ b/parachain/pallets/outbound-queue/src/lib.rs @@ -173,7 +173,7 @@ pub mod pallet { pub enum Event { /// Message has been queued and will be processed in the future MessageQueued { - /// ID of the message. Usually the XCM message hash. + /// ID of the message. Usually the XCM message hash or a SetTopic. id: H256, }, /// Message will be committed at the end of current block. From now on, to track the @@ -352,30 +352,31 @@ pub mod pallet { } // Decode bytes into versioned message - let versioned_enqueued_message: VersionedQueuedMessage = + let versioned_queued_message: VersionedQueuedMessage = VersionedQueuedMessage::decode(&mut message).map_err(|_| Corrupt)?; // Convert versioned message into latest supported message version - let enqueued_message: QueuedMessage = - versioned_enqueued_message.try_into().map_err(|_| Unsupported)?; + let queued_message: QueuedMessage = + versioned_queued_message.try_into().map_err(|_| Unsupported)?; - let next_nonce = Nonce::::get(enqueued_message.origin).saturating_add(1); + let next_nonce = Nonce::::get(queued_message.origin).saturating_add(1); - let command = enqueued_message.command.index(); - let params = enqueued_message.command.abi_encode(); - let max_dispatch_gas = T::GasMeter::maximum_required(&enqueued_message.command) as u128; - let max_refund = Self::calculate_maximum_gas_refund(&enqueued_message.command); + let command = queued_message.command.index(); + let params = queued_message.command.abi_encode(); + let max_dispatch_gas = T::GasMeter::maximum_required(&queued_message.command) as u128; + let max_refund = Self::calculate_maximum_gas_refund(&queued_message.command); let reward = Self::fee_config().reward; // Construct the final committed message let message = CommittedMessage { - origin: enqueued_message.origin, + origin: queued_message.origin, nonce: next_nonce, command, params, max_dispatch_gas, max_refund, reward, + id: queued_message.id, }; // ABI-encode and hash the prepared message @@ -384,10 +385,10 @@ pub mod pallet { Messages::::append(Box::new(message)); MessageLeaves::::append(message_abi_encoded_hash); - Nonce::::set(enqueued_message.origin, next_nonce); + Nonce::::set(queued_message.origin, next_nonce); Self::deposit_event(Event::MessageAccepted { - id: enqueued_message.id, + id: queued_message.id, nonce: next_nonce, }); diff --git a/parachain/pallets/outbound-queue/src/mock.rs b/parachain/pallets/outbound-queue/src/mock.rs index ed10932c9e..794c953faa 100644 --- a/parachain/pallets/outbound-queue/src/mock.rs +++ b/parachain/pallets/outbound-queue/src/mock.rs @@ -127,6 +127,7 @@ where T: Config, { Message { + id: H256::zero(), origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -142,6 +143,7 @@ where T: Config, { Message { + id: H256::zero(), origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -156,6 +158,7 @@ where pub fn mock_message(sibling_para_id: u32) -> Message { Message { + id: H256::zero(), origin: sibling_para_id.into(), command: Command::AgentExecute { agent_id: Default::default(), diff --git a/parachain/pallets/outbound-queue/src/send_message_impl.rs b/parachain/pallets/outbound-queue/src/send_message_impl.rs index 4912b9100e..080bde21be 100644 --- a/parachain/pallets/outbound-queue/src/send_message_impl.rs +++ b/parachain/pallets/outbound-queue/src/send_message_impl.rs @@ -8,7 +8,7 @@ use frame_support::{ }; use snowbridge_core::outbound::{ AggregateMessageOrigin, ExportOrigin, Fee, Message, QueuedMessage, SendError, SendMessage, - VersionedQueuedMessage, + Ticket as TicketTrait, VersionedQueuedMessage, }; use sp_core::H256; use sp_runtime::BoundedVec; @@ -18,23 +18,35 @@ pub type MaxEnqueuedMessageSizeOf = <::MessageQueue as EnqueueMessage>::MaxMessageLen; #[derive(Encode, Decode, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound)] -pub struct Ticket> { - pub id: H256, +pub struct Ticket +where + T: Config, +{ + pub message_id: H256, pub origin: ParaId, - pub message: BoundedVec, + pub message: BoundedVec>, } -impl SendMessage for Pallet { - type Ticket = Ticket>; +impl TicketTrait for Ticket +where + T: Config, +{ + fn message_id(&self) -> H256 { + self.message_id + } +} + +impl SendMessage for Pallet +where + T: Config, +{ + type Ticket = Ticket; type Balance = T::Balance; fn validate(message: &Message) -> Result<(Self::Ticket, Fee), SendError> { // The inner payload should not be too large let payload = message.command.abi_encode(); - // Create a message id for tracking progress in submission pipeline - let message_id: H256 = sp_io::hashing::blake2_256(&(message.encode())).into(); - ensure!( payload.len() < T::MaxMessagePayloadSize::get() as usize, SendError::MessageTooLarge @@ -43,7 +55,7 @@ impl SendMessage for Pallet { let fee = Self::calculate_fee(&message.command); let queued_message: VersionedQueuedMessage = QueuedMessage { - id: message_id, + id: message.id, origin: message.origin, command: message.command.clone(), } @@ -51,7 +63,7 @@ impl SendMessage for Pallet { // The whole message should not be too large let encoded = queued_message.encode().try_into().map_err(|_| SendError::MessageTooLarge)?; - let ticket = Ticket { id: message_id, origin: message.origin, message: encoded }; + let ticket = Ticket { message_id: message.id, origin: message.origin, message: encoded }; Ok((ticket, fee)) } @@ -79,7 +91,7 @@ impl SendMessage for Pallet { let message = ticket.message.as_bounded_slice(); T::MessageQueue::enqueue_message(message, origin); - Self::deposit_event(Event::MessageQueued { id: ticket.id }); - Ok(ticket.id) + Self::deposit_event(Event::MessageQueued { id: ticket.message_id }); + Ok(ticket.message_id) } } diff --git a/parachain/pallets/outbound-queue/src/types.rs b/parachain/pallets/outbound-queue/src/types.rs index bdfd51e942..db75a2c6b5 100644 --- a/parachain/pallets/outbound-queue/src/types.rs +++ b/parachain/pallets/outbound-queue/src/types.rs @@ -4,6 +4,7 @@ use frame_support::traits::ProcessMessage; use scale_info::TypeInfo; use serde::{Deserialize, Serialize}; use sp_arithmetic::FixedU128; +use sp_core::H256; use sp_runtime::{traits::Zero, RuntimeDebug}; use sp_std::prelude::*; @@ -33,6 +34,8 @@ pub struct CommittedMessage { pub max_refund: u128, /// Reward in ether for delivering this message, in addition to the gas refund pub reward: u128, + /// Message ID (Used for tracing messages across route, has no role in consensus) + pub id: H256, } /// Convert message into an ABI-encoded form for delivery to the InboundQueue contract on Ethereum @@ -46,6 +49,7 @@ impl From for Token { Token::Uint(x.max_dispatch_gas.into()), Token::Uint(x.max_refund.into()), Token::Uint(x.reward.into()), + Token::FixedBytes(Vec::from(x.id.as_ref())), ]) } } diff --git a/parachain/primitives/core/src/outbound.rs b/parachain/primitives/core/src/outbound.rs index cd15d33963..57723a17f2 100644 --- a/parachain/primitives/core/src/outbound.rs +++ b/parachain/primitives/core/src/outbound.rs @@ -4,7 +4,6 @@ pub use polkadot_parachain_primitives::primitives::Id as ParaId; use scale_info::TypeInfo; use sp_arithmetic::traits::{BaseArithmetic, Unsigned}; use sp_core::{RuntimeDebug, H256}; - pub use v1::{AgentExecuteCommand, Command, Initializer, Message, OperatingMode, QueuedMessage}; /// Enqueued outbound messages need to be versioned to prevent data corruption @@ -43,6 +42,8 @@ mod v1 { #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct Message { + /// ID for this message. One will be automatically generated if not provided + pub id: H256, /// The parachain from which the message originated pub origin: ParaId, /// The stable ID for a receiving gateway contract @@ -225,7 +226,7 @@ mod v1 { #[derive(Encode, Decode, Clone, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct QueuedMessage { - /// Message ID (usually hash of message) + /// Message ID pub id: H256, /// ID of source parachain pub origin: ParaId, @@ -266,7 +267,7 @@ where /// A trait for sending messages to Ethereum pub trait SendMessage { - type Ticket: Clone + Encode + Decode; + type Ticket: Ticket; type Balance: BaseArithmetic + Unsigned + Copy; /// Validate an outbound message and return a tuple: @@ -278,6 +279,10 @@ pub trait SendMessage { fn deliver(ticket: Self::Ticket) -> Result; } +pub trait Ticket: Encode + Decode + Clone { + fn message_id(&self) -> H256; +} + /// Reasons why sending to Ethereum could not be initiated #[derive(Copy, Clone, Encode, Decode, PartialEq, Eq, RuntimeDebug, PalletError, TypeInfo)] pub enum SendError { diff --git a/parachain/primitives/ethereum/Cargo.toml b/parachain/primitives/ethereum/Cargo.toml index 7ff906b19a..832a7bffe0 100644 --- a/parachain/primitives/ethereum/Cargo.toml +++ b/parachain/primitives/ethereum/Cargo.toml @@ -14,8 +14,7 @@ ethereum-types = { version = "0.14.1", default-features = false, features = [ "c hex = { package = "rustc-hex", version = "2.1.0", default-features = false } hex-literal = { version = "0.4.1", default-features = false } parity-bytes = { version = "0.1.2", default-features = false } -rlp = { version = "0.5", default-features = false } -#getrandom = { version = "0.2.1", features = [ "js" ] } +rlp = { version = "0.5.2", default-features = false } sp-io = { path = "../../../polkadot-sdk/substrate/primitives/io", default-features = false } sp-std = { path = "../../../polkadot-sdk/substrate/primitives/std", default-features = false } diff --git a/parachain/primitives/router/src/inbound/mod.rs b/parachain/primitives/router/src/inbound/mod.rs index 54447cb01f..235ea98c71 100644 --- a/parachain/primitives/router/src/inbound/mod.rs +++ b/parachain/primitives/router/src/inbound/mod.rs @@ -83,6 +83,7 @@ pub enum ConvertMessageError { /// convert the inbound message to xcm which will be forwarded to the destination chain pub trait ConvertMessage { + /// Converts a versioned message into an XCM message and an optional topicID fn convert(message: VersionedMessage) -> Result, ConvertMessageError>; } diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index a2b8620fde..1123d29231 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -25,7 +25,6 @@ where UniversalLocation: Get, GatewayLocation: Get, OutboundQueue: SendMessage, - OutboundQueue::Ticket: Encode + Decode, AgentHashedDescription: ConvertLocation, { type Ticket = (Vec, XcmHash); @@ -98,7 +97,7 @@ where })?; let mut converter = XcmConverter::new(&message, &gateway_network, &gateway_address); - let (agent_execute_command, max_target_fee) = converter.convert().map_err(|err|{ + let (agent_execute_command, max_target_fee, topic_id) = converter.convert().map_err(|err|{ log::error!(target: "xcm::ethereum_blob_exporter", "unroutable due to pattern matching error '{err:?}'."); SendError::Unroutable })?; @@ -119,6 +118,7 @@ where }; let outbound_message = Message { + id: topic_id.into(), origin: para_id.into(), command: Command::AgentExecute { agent_id, command: agent_execute_command }, }; @@ -132,7 +132,7 @@ where // convert fee to MultiAsset let fee = MultiAsset::from((MultiLocation::parent(), fee.total())).into(); - Ok(((ticket.encode(), XcmHash::default()), fee)) + Ok(((ticket.encode(), topic_id.into()), fee)) } fn deliver(blob: (Vec, XcmHash)) -> Result { @@ -142,13 +142,13 @@ where SendError::NotApplicable })?; - let message_hash = OutboundQueue::deliver(ticket).map_err(|_| { + let message_id = OutboundQueue::deliver(ticket).map_err(|_| { log::error!(target: "xcm::ethereum_blob_exporter", "OutboundQueue submit of message failed"); SendError::Transport("other transport error") })?; - log::info!(target: "xcm::ethereum_blob_exporter", "message delivered {message_hash:#?}."); - Ok(message_hash.into()) + log::info!(target: "xcm::ethereum_blob_exporter", "message delivered {message_id:#?}."); + Ok(message_id.into()) } } @@ -187,7 +187,7 @@ impl<'a, Call> XcmConverter<'a, Call> { fn convert( &mut self, - ) -> Result<(AgentExecuteCommand, Option<&'a MultiAsset>), XcmConverterError> { + ) -> Result<(AgentExecuteCommand, Option<&'a MultiAsset>, [u8; 32]), XcmConverterError> { // Get target fees if specified. let max_target_fee = self.fee_info()?; @@ -195,7 +195,7 @@ impl<'a, Call> XcmConverter<'a, Call> { let result = self.native_tokens_unlock_message()?; // Match last set topic. Later could use message id for replies - let _ = match self.next()? { + let topic_id = match self.next()? { SetTopic(id) => id, _ => return Err(XcmConverterError::SetTopicExpected), }; @@ -205,7 +205,7 @@ impl<'a, Call> XcmConverter<'a, Call> { return Err(XcmConverterError::EndOfXcmMessageExpected) } - Ok((result, max_target_fee)) + Ok((result, max_target_fee, *topic_id)) } fn fee_info(&mut self) -> Result, XcmConverterError> { @@ -307,7 +307,7 @@ impl<'a, Call> XcmConverter<'a, Call> { mod tests { use frame_support::parameter_types; use hex_literal::hex; - use snowbridge_core::outbound::{Fee, SendError}; + use snowbridge_core::outbound::{Fee, SendError, Ticket as TicketTrait}; use xcm::v3::prelude::SendError as XcmSendError; use xcm_builder::{DescribeAllTerminal, DescribeFamily, HashedDescription}; @@ -316,6 +316,7 @@ mod tests { use super::*; parameter_types! { + const MaxMessageSize: u32 = u32::MAX; const RelayNetwork: NetworkId = Polkadot; const UniversalLocation: InteriorMultiLocation = X2(GlobalConsensus(RelayNetwork::get()), Parachain(1013)); const BridgedNetwork: NetworkId = Ethereum{ chain_id: 1 }; @@ -326,13 +327,22 @@ mod tests { const GATEWAY: [u8; 20] = hex!("D184c103F7acc340847eEE82a0B909E3358bc28d"); + #[derive(Encode, Decode, Clone)] + struct MockTicket(); + + impl TicketTrait for MockTicket { + fn message_id(&self) -> H256 { + H256::zero() + } + } + struct MockOkOutboundQueue; impl SendMessage for MockOkOutboundQueue { - type Ticket = (); + type Ticket = MockTicket; type Balance = u128; - fn validate(_: &Message) -> Result<((), Fee), SendError> { - Ok(((), Fee { local: 1, remote: 1 })) + fn validate(_: &Message) -> Result<(Self::Ticket, Fee), SendError> { + Ok((MockTicket(), Fee { local: 1, remote: 1 })) } fn deliver(_: Self::Ticket) -> Result { @@ -341,10 +351,10 @@ mod tests { } struct MockErrOutboundQueue; impl SendMessage for MockErrOutboundQueue { - type Ticket = (); + type Ticket = MockTicket; type Balance = u128; - fn validate(_: &Message) -> Result<((), Fee), SendError> { + fn validate(_: &Message) -> Result<(Self::Ticket, Fee), SendError> { Err(SendError::MessageTooLarge) } @@ -745,7 +755,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, Some(&fee)))); + assert_eq!(result, Ok((expected_payload, Some(&fee), [0; 32]))); } #[test] @@ -785,7 +795,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, None))); + assert_eq!(result, Ok((expected_payload, None, [0; 32]))); } #[test] @@ -825,7 +835,7 @@ mod tests { amount: 1000, }; let result = converter.convert(); - assert_eq!(result, Ok((expected_payload, None))); + assert_eq!(result, Ok((expected_payload, None, [0; 32]))); } #[test] diff --git a/polkadot-sdk b/polkadot-sdk index dab8646cfd..ce31f30276 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit dab8646cfdd5fe8ffe82335feda064cd4b8a5f2c +Subproject commit ce31f302769f26f61a95efda3c50508cfb0bca46 diff --git a/relayer/contracts/gateway.go b/relayer/contracts/gateway.go index 75c8d29c0f..3a1979a228 100644 --- a/relayer/contracts/gateway.go +++ b/relayer/contracts/gateway.go @@ -38,6 +38,7 @@ type InboundMessage struct { MaxDispatchGas *big.Int MaxRefund *big.Int Reward *big.Int + Id [32]byte } // VerificationDigestItem is an auto generated low-level Go binding around an user-defined struct. @@ -84,7 +85,7 @@ type VerificationProof struct { // GatewayMetaData contains all meta data concerning the Gateway contract. var GatewayMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"topicID\",\"type\":\"bytes32\"}],\"name\":\"Topic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // GatewayABI is the input ABI used to generate the binding from. @@ -483,23 +484,23 @@ func (_Gateway *GatewayTransactorSession) SendToken0(token common.Address, desti return _Gateway.Contract.SendToken0(&_Gateway.TransactOpts, token, destinationChain, destinationAddress, amount) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewayTransactor) SubmitInbound(opts *bind.TransactOpts, message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.contract.Transact(opts, "submitInbound", message, leafProof, headerProof) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewaySession) SubmitInbound(message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.Contract.SubmitInbound(&_Gateway.TransactOpts, message, leafProof, headerProof) } -// SubmitInbound is a paid mutator transaction binding the contract method 0xa7397d76. +// SubmitInbound is a paid mutator transaction binding the contract method 0x5a058f67. // -// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() +// Solidity: function submitInbound((uint256,uint64,uint8,bytes,uint256,uint256,uint256,bytes32) message, bytes32[] leafProof, ((bytes32,uint256,bytes32,bytes32,(uint256,bytes4,bytes)[]),(uint256,uint256,bytes32[]),(uint8,uint32,bytes32,uint64,uint32,bytes32),bytes32[],uint256) headerProof) returns() func (_Gateway *GatewayTransactorSession) SubmitInbound(message InboundMessage, leafProof [][32]byte, headerProof VerificationProof) (*types.Transaction, error) { return _Gateway.Contract.SubmitInbound(&_Gateway.TransactOpts, message, leafProof, headerProof) } @@ -1150,40 +1151,51 @@ func (it *GatewayInboundMessageDispatchedIterator) Close() error { // GatewayInboundMessageDispatched represents a InboundMessageDispatched event raised by the Gateway contract. type GatewayInboundMessageDispatched struct { - Origin *big.Int - Nonce uint64 - Success bool - Raw types.Log // Blockchain specific contextual infos + Origin *big.Int + Nonce uint64 + MessageID [32]byte + Success bool + Raw types.Log // Blockchain specific contextual infos } -// FilterInboundMessageDispatched is a free log retrieval operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// FilterInboundMessageDispatched is a free log retrieval operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) -func (_Gateway *GatewayFilterer) FilterInboundMessageDispatched(opts *bind.FilterOpts, origin []*big.Int) (*GatewayInboundMessageDispatchedIterator, error) { +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) +func (_Gateway *GatewayFilterer) FilterInboundMessageDispatched(opts *bind.FilterOpts, origin []*big.Int, messageID [][32]byte) (*GatewayInboundMessageDispatchedIterator, error) { var originRule []interface{} for _, originItem := range origin { originRule = append(originRule, originItem) } - logs, sub, err := _Gateway.contract.FilterLogs(opts, "InboundMessageDispatched", originRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "InboundMessageDispatched", originRule, messageIDRule) if err != nil { return nil, err } return &GatewayInboundMessageDispatchedIterator{contract: _Gateway.contract, event: "InboundMessageDispatched", logs: logs, sub: sub}, nil } -// WatchInboundMessageDispatched is a free log subscription operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// WatchInboundMessageDispatched is a free log subscription operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) -func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchOpts, sink chan<- *GatewayInboundMessageDispatched, origin []*big.Int) (event.Subscription, error) { +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) +func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchOpts, sink chan<- *GatewayInboundMessageDispatched, origin []*big.Int, messageID [][32]byte) (event.Subscription, error) { var originRule []interface{} for _, originItem := range origin { originRule = append(originRule, originItem) } - logs, sub, err := _Gateway.contract.WatchLogs(opts, "InboundMessageDispatched", originRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "InboundMessageDispatched", originRule, messageIDRule) if err != nil { return nil, err } @@ -1215,9 +1227,9 @@ func (_Gateway *GatewayFilterer) WatchInboundMessageDispatched(opts *bind.WatchO }), nil } -// ParseInboundMessageDispatched is a log parse operation binding the contract event 0xc413674585e5f4244fd69ce2c9587aac57f3fdaf6b337a1f39317d2ffa1279f1. +// ParseInboundMessageDispatched is a log parse operation binding the contract event 0xe88d4734b8bcb71455d9b1ece51ef7aae126a1b670e20b299eb98d606ff7a5dc. // -// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bool success) +// Solidity: event InboundMessageDispatched(uint256 indexed origin, uint64 nonce, bytes32 indexed messageID, bool success) func (_Gateway *GatewayFilterer) ParseInboundMessageDispatched(log types.Log) (*GatewayInboundMessageDispatched, error) { event := new(GatewayInboundMessageDispatched) if err := _Gateway.contract.UnpackLog(event, "InboundMessageDispatched", log); err != nil { @@ -1432,38 +1444,49 @@ func (it *GatewayOutboundMessageAcceptedIterator) Close() error { type GatewayOutboundMessageAccepted struct { Destination *big.Int Nonce uint64 + MessageID [32]byte Payload []byte Raw types.Log // Blockchain specific contextual infos } -// FilterOutboundMessageAccepted is a free log retrieval operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// FilterOutboundMessageAccepted is a free log retrieval operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, destination []*big.Int) (*GatewayOutboundMessageAcceptedIterator, error) { +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) +func (_Gateway *GatewayFilterer) FilterOutboundMessageAccepted(opts *bind.FilterOpts, destination []*big.Int, messageID [][32]byte) (*GatewayOutboundMessageAcceptedIterator, error) { var destinationRule []interface{} for _, destinationItem := range destination { destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destinationRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "OutboundMessageAccepted", destinationRule, messageIDRule) if err != nil { return nil, err } return &GatewayOutboundMessageAcceptedIterator{contract: _Gateway.contract, event: "OutboundMessageAccepted", logs: logs, sub: sub}, nil } -// WatchOutboundMessageAccepted is a free log subscription operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// WatchOutboundMessageAccepted is a free log subscription operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) -func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOpts, sink chan<- *GatewayOutboundMessageAccepted, destination []*big.Int) (event.Subscription, error) { +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) +func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOpts, sink chan<- *GatewayOutboundMessageAccepted, destination []*big.Int, messageID [][32]byte) (event.Subscription, error) { var destinationRule []interface{} for _, destinationItem := range destination { destinationRule = append(destinationRule, destinationItem) } - logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destinationRule) + var messageIDRule []interface{} + for _, messageIDItem := range messageID { + messageIDRule = append(messageIDRule, messageIDItem) + } + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "OutboundMessageAccepted", destinationRule, messageIDRule) if err != nil { return nil, err } @@ -1495,9 +1518,9 @@ func (_Gateway *GatewayFilterer) WatchOutboundMessageAccepted(opts *bind.WatchOp }), nil } -// ParseOutboundMessageAccepted is a log parse operation binding the contract event 0xd56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fece. +// ParseOutboundMessageAccepted is a log parse operation binding the contract event 0x5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169. // -// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes payload) +// Solidity: event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload) func (_Gateway *GatewayFilterer) ParseOutboundMessageAccepted(log types.Log) (*GatewayOutboundMessageAccepted, error) { event := new(GatewayOutboundMessageAccepted) if err := _Gateway.contract.UnpackLog(event, "OutboundMessageAccepted", log); err != nil { @@ -1797,6 +1820,140 @@ func (_Gateway *GatewayFilterer) ParseTokenSent(log types.Log) (*GatewayTokenSen return event, nil } +// GatewayTopicIterator is returned from FilterTopic and is used to iterate over the raw logs and unpacked data for Topic events raised by the Gateway contract. +type GatewayTopicIterator struct { + Event *GatewayTopic // 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 *GatewayTopicIterator) 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(GatewayTopic) + 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(GatewayTopic) + 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 *GatewayTopicIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *GatewayTopicIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// GatewayTopic represents a Topic event raised by the Gateway contract. +type GatewayTopic struct { + TopicID [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTopic is a free log retrieval operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. +// +// Solidity: event Topic(bytes32 topicID) +func (_Gateway *GatewayFilterer) FilterTopic(opts *bind.FilterOpts) (*GatewayTopicIterator, error) { + + logs, sub, err := _Gateway.contract.FilterLogs(opts, "Topic") + if err != nil { + return nil, err + } + return &GatewayTopicIterator{contract: _Gateway.contract, event: "Topic", logs: logs, sub: sub}, nil +} + +// WatchTopic is a free log subscription operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. +// +// Solidity: event Topic(bytes32 topicID) +func (_Gateway *GatewayFilterer) WatchTopic(opts *bind.WatchOpts, sink chan<- *GatewayTopic) (event.Subscription, error) { + + logs, sub, err := _Gateway.contract.WatchLogs(opts, "Topic") + 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(GatewayTopic) + if err := _Gateway.contract.UnpackLog(event, "Topic", 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 +} + +// ParseTopic is a log parse operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. +// +// Solidity: event Topic(bytes32 topicID) +func (_Gateway *GatewayFilterer) ParseTopic(log types.Log) (*GatewayTopic, error) { + event := new(GatewayTopic) + if err := _Gateway.contract.UnpackLog(event, "Topic", 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 2519b88837..c39a7fa18e 100644 --- a/relayer/relays/execution/main.go +++ b/relayer/relays/execution/main.go @@ -255,7 +255,7 @@ func (r *Relay) findEvents( } func (r *Relay) findEventsWithFilter(opts *bind.FilterOpts, paraID uint32, start uint64) (bool, []*contracts.GatewayOutboundMessageAccepted, error) { - iter, err := r.gatewayContract.FilterOutboundMessageAccepted(opts, []*big.Int{big.NewInt(int64(paraID))}) + iter, err := r.gatewayContract.FilterOutboundMessageAccepted(opts, []*big.Int{big.NewInt(int64(paraID))}, [][32]byte{}) if err != nil { return false, nil, err } diff --git a/relayer/relays/parachain/types.go b/relayer/relays/parachain/types.go index 9bdff130e8..f002002236 100644 --- a/relayer/relays/parachain/types.go +++ b/relayer/relays/parachain/types.go @@ -90,6 +90,7 @@ type OutboundQueueMessage struct { MaxDispatchGas types.U128 MaxRefund types.U128 Reward types.U128 + ID types.Bytes32 } func (m OutboundQueueMessage) IntoInboundMessage() contracts.InboundMessage { @@ -101,6 +102,7 @@ func (m OutboundQueueMessage) IntoInboundMessage() contracts.InboundMessage { MaxDispatchGas: m.MaxDispatchGas.Int, MaxRefund: m.MaxRefund.Int, Reward: m.Reward.Int, + Id: m.ID, } } diff --git a/web/packages/test/scripts/set-env.sh b/web/packages/test/scripts/set-env.sh index 74a703ced2..00d1e23fc5 100755 --- a/web/packages/test/scripts/set-env.sh +++ b/web/packages/test/scripts/set-env.sh @@ -77,10 +77,12 @@ export RANDAO_COMMIT_DELAY="${ETH_RANDAO_DELAY:-3}" export RANDAO_COMMIT_EXP="${ETH_RANDAO_EXP:-3}" export MINIMUM_REQUIRED_SIGNATURES="${MINIMUM_REQUIRED_SIGNATURES:-16}" +export REJECT_OUTBOUND_MESSAGES=false export DEFAULT_FEE="${ETH_DEFAULT_FEE:-1}" export CREATE_CALL_INDEX="${ETH_CREATE_CALL_INDEX:-0x3500}" + export REGISTER_NATIVE_TOKEN_FEE="${ETH_REGISTER_NATIVE_TOKEN_FEE:-0}" export SEND_NATIVE_TOKEN_FEE="${ETH_SEND_NATIVE_TOKEN_FEE:-0}" From 273542b9cd4e41d22a3083f538dae97d8da7385b Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Tue, 7 Nov 2023 20:56:59 +0200 Subject: [PATCH 02/20] Add support for message IDs --- contracts/test/Gateway.t.sol | 16 +- parachain/Cargo.lock | 641 +++++++++++++++--- parachain/pallets/inbound-queue/Cargo.toml | 6 +- .../src/benchmarking/fixtures.rs | 2 +- .../pallets/inbound-queue/src/envelope.rs | 76 +-- parachain/pallets/inbound-queue/src/lib.rs | 8 +- parachain/primitives/router/Cargo.toml | 1 + polkadot-sdk | 2 +- .../test/scripts/configure-bridgehub.sh | 1 - 9 files changed, 595 insertions(+), 158 deletions(-) diff --git a/contracts/test/Gateway.t.sol b/contracts/test/Gateway.t.sol index c7c622a43f..af5ae9b140 100644 --- a/contracts/test/Gateway.t.sol +++ b/contracts/test/Gateway.t.sol @@ -28,20 +28,6 @@ import {WETH9} from "canonical-weth/WETH9.sol"; import "./mocks/GatewayUpgradeMock.sol"; contract GatewayTest is Test { - event InboundMessageDispatched(ParaID indexed origin, uint64 nonce, bool result); - event OutboundMessageAccepted(ParaID indexed dest, uint64 nonce, bytes payload); - event NativeTokensUnlocked(address token, address recipient, uint256 amount); - event TokenRegistrationSent(address token); - event TokenSent( - address indexed sender, address indexed token, ParaID destinationChain, bytes destinationAddress, uint128 amount - ); - event AgentCreated(bytes32 agentID, address agent); - event ChannelCreated(ParaID indexed paraID); - event ChannelUpdated(ParaID indexed paraID); - - event Upgraded(address indexed implementation); - event Initialized(uint256 d0, uint256 d1); - ParaID public bridgeHubParaID = ParaID.wrap(1001); bytes32 public bridgeHubAgentID = keccak256("1001"); address public bridgeHubAgent; @@ -536,7 +522,7 @@ contract GatewayTest is Test { function testRegisterToken() public { vm.expectEmit(false, false, false, true); - emit TokenRegistrationSent(address(token)); + emit IGateway.TokenRegistrationSent(address(token)); vm.expectEmit(true, false, false, false); emit IGateway.OutboundMessageAccepted(assetHubParaID, 1, messageID, bytes("")); diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index c26c95b7e2..7da754e114 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -59,6 +59,66 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloy-primitives" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0628ec0ba5b98b3370bb6be17b12f23bfce8ee4ad83823325a20546d9b03b78" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more", + "hex-literal", + "itoa", + "proptest", + "rand 0.8.5", + "ruint", + "serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-rlp" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" +dependencies = [ + "arrayvec 0.7.2", + "bytes", + "smol_str", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a98ad1696a2e17f010ae8e43e9f2a1e930ed176a8e3ff77acfeff6dfb07b42c" +dependencies = [ + "const-hex", + "dunce", + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.38", + "syn-solidity", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "alloy-sol-types" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98d7107bed88e8f09f0ddcc3335622d87bfb6821f3e0c7473329fb1cfad5e015" +dependencies = [ + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + [[package]] name = "amcl" version = "0.3.0" @@ -122,8 +182,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb00293ba84f51ce3bd026bd0de55899c4e68f0a39a5728cebae3a73ffdc0a4f" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -133,9 +193,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", ] [[package]] @@ -144,10 +204,10 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" dependencies = [ - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", "itertools", @@ -163,8 +223,26 @@ checksum = "f9cde0f2aa063a2a5c28d39b47761aa102bda7c13c84fc118a61b87c7b2f785c" dependencies = [ "ark-bls12-381", "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.4.2", + "ark-std 0.4.0", +] + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", ] [[package]] @@ -173,20 +251,30 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "digest 0.10.7", "itertools", "num-bigint", "num-traits", "paste", - "rustc_version", + "rustc_version 0.4.0", "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.4.2" @@ -197,6 +285,18 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-macros" version = "0.4.2" @@ -216,9 +316,9 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "derivative", "hashbrown 0.13.2", ] @@ -230,9 +330,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51bd73bb6ddb72630987d37fa963e99196896c0d0ea81b7c894567e74a2f83af" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "parity-scale-codec", "scale-info", ] @@ -243,15 +343,25 @@ version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ "ark-ec", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "ark-transcript", "digest 0.10.7", "rand_core 0.6.4", "zeroize", ] +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + [[package]] name = "ark-serialize" version = "0.4.2" @@ -259,7 +369,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.4.0", "digest 0.10.7", "num-bigint", ] @@ -275,6 +385,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "ark-std" version = "0.4.0" @@ -290,9 +410,9 @@ name = "ark-transcript" version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "digest 0.10.7", "rand_core 0.6.4", "sha3", @@ -350,6 +470,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "auto_impl" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fee3da8ef1276b0bee5dd1c7258010d8fffd31801447323115a25560e1327b89" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -379,9 +511,9 @@ dependencies = [ "ark-bls12-381", "ark-ec", "ark-ed-on-bls12-381-bandersnatch", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "dleq_vrf", "fflonk", "merlin 3.0.0", @@ -432,6 +564,21 @@ dependencies = [ "unicode-normalization", ] +[[package]] +name = "bit-set" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" @@ -444,6 +591,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" + [[package]] name = "bitvec" version = "1.0.1" @@ -643,10 +796,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/ring-proof#edd1e90b847e560bf60fc2e8712235ccfa11a9a9" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "fflonk", "merlin 3.0.0", "rand_chacha 0.3.1", @@ -668,6 +821,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5104de16b218eddf8e34ffe2f86f74bfa4e61e95a1b89732fccf6325efd0557" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.2" @@ -840,7 +1006,7 @@ dependencies = [ "digest 0.10.7", "fiat-crypto", "platforms", - "rustc_version", + "rustc_version 0.4.0", "subtle", "zeroize", ] @@ -941,7 +1107,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "rustc_version", + "rustc_version 0.4.0", "syn 1.0.109", ] @@ -980,11 +1146,11 @@ version = "0.0.2" source = "git+https://github.com/w3f/ring-vrf?rev=4b09416#4b09416fd23383ec436ddac127d58c7b7cd392c6" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-scale", "ark-secret-scalar", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "ark-transcript", "arrayvec 0.7.2", "rand_core 0.6.4", @@ -1018,6 +1184,12 @@ dependencies = [ "walkdir", ] +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "dyn-clonable" version = "0.9.0" @@ -1155,6 +1327,16 @@ dependencies = [ "winapi", ] +[[package]] +name = "errno" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + [[package]] name = "errno-dragonfly" version = "0.1.2" @@ -1230,6 +1412,23 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec 0.7.2", + "auto_impl", + "bytes", +] + [[package]] name = "ff" version = "0.13.0" @@ -1246,10 +1445,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/fflonk#e141d4b6f42fb481aefe1b479788694945b6940d" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "merlin 3.0.0", ] @@ -1271,6 +1470,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.1.0" @@ -1321,7 +1526,7 @@ name = "frame-support" version = "4.0.0-dev" dependencies = [ "aquamarine", - "bitflags", + "bitflags 1.3.2", "docify", "environmental", "frame-metadata", @@ -1833,7 +2038,7 @@ checksum = "09270fd4fa1111bc614ed2246c7ef56239a3063d5be0d1ec3b589c505d400aeb" dependencies = [ "hermit-abi 0.3.1", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -1894,6 +2099,12 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + [[package]] name = "libsecp256k1" version = "0.7.1" @@ -1966,6 +2177,12 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +[[package]] +name = "linux-raw-sys" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f" + [[package]] name = "lock_api" version = "0.4.9" @@ -2069,7 +2286,7 @@ version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b20a59d985586e4a5aef64564ac77299f8586d8be6cf9106a5a40207e8908efb" dependencies = [ - "rustix", + "rustix 0.36.11", ] [[package]] @@ -2223,11 +2440,12 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.15" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" dependencies = [ "autocfg", + "libm", ] [[package]] @@ -2393,9 +2611,9 @@ checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.2.16", "smallvec", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -2419,6 +2637,17 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" +[[package]] +name = "pest" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae9cee2a55a544be8b89dc6848072af97a20f2422603c10865be2a42b580fff5" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -2573,6 +2802,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "proptest" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c003ac8c77cb07bb74f5f198bce836a689bcd5a42574612bf14d17bfd08c20e" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.4.1", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift", + "regex-syntax 0.7.5", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "psm" version = "0.1.21" @@ -2582,6 +2831,12 @@ dependencies = [ "cc", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.33" @@ -2668,6 +2923,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "rawpointer" version = "0.2.1" @@ -2680,7 +2944,16 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" dependencies = [ - "bitflags", + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", ] [[package]] @@ -2711,7 +2984,7 @@ checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.6.28", ] [[package]] @@ -2720,7 +2993,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "regex-syntax", + "regex-syntax 0.6.28", ] [[package]] @@ -2729,6 +3002,12 @@ version = "0.6.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +[[package]] +name = "regex-syntax" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" + [[package]] name = "rfc6979" version = "0.4.0" @@ -2745,10 +3024,10 @@ version = "0.1.0" source = "git+https://github.com/w3f/ring-proof#edd1e90b847e560bf60fc2e8712235ccfa11a9a9" dependencies = [ "ark-ec", - "ark-ff", + "ark-ff 0.4.2", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.4.2", + "ark-std 0.4.0", "blake2", "common", "fflonk", @@ -2765,6 +3044,36 @@ dependencies = [ "rustc-hex", ] +[[package]] +name = "ruint" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "724fd11728a3804e9944b14cab63825024c40bf42f8af87c8b5d97c4bbacf426" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp", + "num-bigint", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e666a5496a0b2186dbcd0ff6106e29e093c15591bde62c20d3842007c6978a09" + [[package]] name = "rustc-demangle" version = "0.1.21" @@ -2777,13 +3086,22 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver", + "semver 1.0.17", ] [[package]] @@ -2792,12 +3110,25 @@ version = "0.36.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db4165c9963ab29e422d6c26fbc1d37f15bace6b2810221f9d925023480fcf0e" dependencies = [ - "bitflags", - "errno", + "bitflags 1.3.2", + "errno 0.2.8", "io-lifetimes", "libc", - "linux-raw-sys", - "windows-sys", + "linux-raw-sys 0.1.4", + "windows-sys 0.45.0", +] + +[[package]] +name = "rustix" +version = "0.38.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3" +dependencies = [ + "bitflags 2.4.1", + "errno 0.3.5", + "libc", + "linux-raw-sys 0.4.10", + "windows-sys 0.48.0", ] [[package]] @@ -2806,6 +3137,18 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5583e89e108996506031660fe09baa5011b9dd0341b89029313006d1fb508d70" +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.12" @@ -2944,12 +3287,30 @@ dependencies = [ "zeroize", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bebd363326d05ec3e2f532ab7660680f3b02130d780c299bca73469d521bc0ed" +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + [[package]] name = "serde" version = "1.0.190" @@ -3092,6 +3453,15 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +[[package]] +name = "smol_str" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74212e6bbe9a4352329b2f68ba3130c15a3f26fe88ff22dbdc6cdd58fa85e99c" +dependencies = [ + "serde", +] + [[package]] name = "snowbridge-beacon-primitives" version = "0.0.1" @@ -3236,12 +3606,13 @@ dependencies = [ name = "snowbridge-inbound-queue" version = "0.1.1" dependencies = [ - "ethabi-decode", + "alloy-sol-types", "frame-benchmarking", "frame-support", "frame-system", "hex-literal", "log", + "num-traits", "pallet-balances", "parity-scale-codec", "rlp", @@ -3424,7 +3795,7 @@ dependencies = [ "array-bytes 6.1.0", "bandersnatch_vrfs", "bip39", - "bitflags", + "bitflags 1.3.2", "blake2", "bounded-collections", "bs58", @@ -3974,6 +4345,18 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn-solidity" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b837ef12ab88835251726eb12237655e61ec8dc8a280085d1961cdc3dfd047" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -3998,6 +4381,19 @@ version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ae9980cab1db3fceee2f6c6f643d5d8de2997c58ee8d25fb0cc8a9e9e7348e5" +[[package]] +name = "tempfile" +version = "3.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef1adac450ad7f4b3c28589471ade84f25f731a7a0fe30d71dfa9f60fd808e5" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix 0.38.21", + "windows-sys 0.48.0", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -4226,6 +4622,12 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "uint" version = "0.9.5" @@ -4238,6 +4640,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-bidi" version = "0.3.13" @@ -4303,8 +4711,8 @@ dependencies = [ "ark-bls12-377", "ark-bls12-381", "ark-ec", - "ark-ff", - "ark-serialize", + "ark-ff 0.4.2", + "ark-serialize 0.4.2", "ark-serialize-derive", "arrayref", "constcat", @@ -4318,6 +4726,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.3.2" @@ -4463,7 +4880,7 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit", "wasmtime-runtime", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4514,7 +4931,7 @@ dependencies = [ "wasmtime-environ", "wasmtime-jit-icache-coherence", "wasmtime-runtime", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4534,7 +4951,7 @@ checksum = "aecae978b13f7f67efb23bd827373ace4578f2137ec110bbf6a4a7cde4121bbd" dependencies = [ "cfg-if", "libc", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4554,11 +4971,11 @@ dependencies = [ "memoffset", "paste", "rand 0.8.5", - "rustix", + "rustix 0.36.11", "wasmtime-asm-macros", "wasmtime-environ", "wasmtime-jit-debug", - "windows-sys", + "windows-sys 0.45.0", ] [[package]] @@ -4630,7 +5047,16 @@ version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" dependencies = [ - "windows-targets", + "windows-targets 0.42.1", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", ] [[package]] @@ -4639,13 +5065,28 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.42.1", + "windows_aarch64_msvc 0.42.1", + "windows_i686_gnu 0.42.1", + "windows_i686_msvc 0.42.1", + "windows_x86_64_gnu 0.42.1", + "windows_x86_64_gnullvm 0.42.1", + "windows_x86_64_msvc 0.42.1", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] @@ -4654,42 +5095,84 @@ version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + [[package]] name = "windows_aarch64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + [[package]] name = "windows_i686_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + [[package]] name = "windows_i686_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + [[package]] name = "windows_x86_64_gnu" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + [[package]] name = "windows_x86_64_msvc" version = "0.42.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "winnow" version = "0.5.17" @@ -4720,9 +5203,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.5.7" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" dependencies = [ "zeroize_derive", ] diff --git a/parachain/pallets/inbound-queue/Cargo.toml b/parachain/pallets/inbound-queue/Cargo.toml index 226b127e42..71d0c20730 100644 --- a/parachain/pallets/inbound-queue/Cargo.toml +++ b/parachain/pallets/inbound-queue/Cargo.toml @@ -16,6 +16,8 @@ scale-info = { version = "2.9.0", default-features = false, features = [ "derive hex-literal = { version = "0.4.1", optional = true } rlp = { version = "0.5.2", default-features = false, optional = true } log = { version = "0.4.20", default-features = false } +alloy-sol-types = { version = "0.4.2", default-features = false } +num-traits = { version = "0.2.16", default-features = false } frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarking", default-features = false, optional = true } frame-support = { path = "../../../polkadot-sdk/substrate/frame/support", default-features = false } @@ -32,7 +34,6 @@ xcm-builder = { package = "staging-xcm-builder", path = "../../../polkadot-sdk/p snowbridge-core = { path = "../../primitives/core", default-features = false } snowbridge-ethereum = { path = "../../primitives/ethereum", default-features = false } snowbridge-router-primitives = { path = "../../primitives/router", default-features = false } -ethabi = { git = "https://github.com/Snowfork/ethabi-decode.git", package = "ethabi-decode", branch = "master", default-features = false } snowbridge-beacon-primitives = { path = "../../primitives/beacon", default-features = false, optional = true } [dev-dependencies] @@ -51,6 +52,7 @@ std = [ "log/std", "codec/std", "scale-info/std", + "alloy-sol-types/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -59,10 +61,10 @@ std = [ "sp-runtime/std", "sp-std/std", "sp-io/std", + "num-traits/std", "snowbridge-core/std", "snowbridge-ethereum/std", "snowbridge-router-primitives/std", - "ethabi/std", "xcm/std", "xcm-builder/std", ] diff --git a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs index ae1e00fb2a..11da799df8 100644 --- a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs +++ b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs @@ -17,7 +17,7 @@ pub fn make_create_message() -> InboundQueueTest { receipts_root: hex!("0115ab735d37c5e4cdb0374d8bb547c6dd6ccaa996d996d1eabc5399a719219e").into(), }, message: Message { - data: hex!("f8db94eda338e4dc46038493b885327842fd3e301cab39f842a0d56f1b8dfd3ba41f19c499ceec5f9546f61befa5f10398a75d7dba53a219fecea000000000000000000000000000000000000000000000000000000000000003e8b88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").to_vec(), + data: hex!("f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").to_vec(), proof: Proof { block_hash: hex!("5f465744c166e9d10dc0031942a59ff82b640053253da517a1b576afdadb0363").into(), tx_index: 0, diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index 0462faa2f0..225d90216d 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -1,23 +1,16 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -use ethabi::{Event, Param, ParamKind, Token}; use snowbridge_core::ParaId; use snowbridge_ethereum::{log::Log, H160}; use sp_core::{RuntimeDebug, H256}; use sp_std::{convert::TryFrom, prelude::*}; -// Used to decode an OutboundMessageAccepted log into an [`Envelope`]. -static EVENT_ABI: &Event = &Event { - signature: "OutboundMessageAccepted(uint256,uint64,bytes32,bytes)", - inputs: &[ - Param { kind: ParamKind::Uint(256), indexed: true }, - Param { kind: ParamKind::Uint(64), indexed: false }, - Param { kind: ParamKind::FixedBytes(32), indexed: true }, - Param { kind: ParamKind::Bytes, indexed: false }, - ], - anonymous: false, -}; +use alloy_sol_types::{abi::token::WordToken, sol, SolEvent}; + +sol! { + event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); +} /// An inbound message that has had its outer envelope decoded. #[derive(Clone, RuntimeDebug)] @@ -34,8 +27,6 @@ pub struct Envelope { pub payload: Vec, } -use log; - #[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug)] pub struct EnvelopeDecodeError; @@ -43,47 +34,22 @@ impl TryFrom for Envelope { type Error = EnvelopeDecodeError; fn try_from(log: Log) -> Result { - log::info!(target: "snowbridge-inbound-queue", "FOO -2"); - - let tokens = EVENT_ABI.decode(log.topics, log.data).map_err(|_| EnvelopeDecodeError)?; - - log::info!(target: "snowbridge-inbound-queue", "FOO -1"); - - let mut iter = tokens.into_iter(); - - let dest = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Uint(dest) => dest.low_u32().into(), - _ => return Err(EnvelopeDecodeError), - }; - - log::info!(target: "snowbridge-inbound-queue", "FOO 0"); - - let nonce = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Uint(nonce) => nonce.low_u64(), - _ => return Err(EnvelopeDecodeError), - }; - - log::info!(target: "snowbridge-inbound-queue", "FOO 1"); - - let message_id = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::FixedBytes(message_id) => { - log::info!(target: "snowbridge-inbound-queue", "FOO 2"); - let message_id: [u8; 32] = - message_id.try_into().map_err(|_| EnvelopeDecodeError)?; - log::info!(target: "snowbridge-inbound-queue", "FOO 3"); - H256::from(&message_id) - }, - _ => return Err(EnvelopeDecodeError), - }; - - log::info!(target: "snowbridge-inbound-queue", "FOO 4"); - - let payload = match iter.next().ok_or(EnvelopeDecodeError)? { - Token::Bytes(payload) => payload, - _ => return Err(EnvelopeDecodeError), - }; - - log::info!(target: "snowbridge-inbound-queue", "FOO 5"); + let topics: Vec = log + .clone() + .topics + .iter() + .map(|t| WordToken::from(*t.as_fixed_bytes())) + .collect(); + + let event = OutboundMessageAccepted::decode_log(topics, &log.data, true).map_err(|e| { + log::error!(target: "ethereum-beacon-client","FOO {:?}", e); + EnvelopeDecodeError + })?; + + let dest: ParaId = event.destination.saturating_to::().into(); + let nonce = event.nonce; + let message_id = H256::from(event.messageID.as_ref()); + let payload = event.payload; Ok(Self { gateway: log.address, dest, nonce, message_id, payload }) } diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index a2d47f9c1e..a6d17d11f2 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -58,7 +58,7 @@ use snowbridge_router_primitives::{ }; use sp_core::H160; use sp_runtime::traits::Saturating; -use sp_std::convert::TryFrom; +use sp_std::{convert::TryFrom, vec}; pub use weights::WeightInfo; use xcm::v3::{ send_xcm, Instruction::SetTopic, Junction::*, Junctions::*, MultiLocation, @@ -207,13 +207,13 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Self::operating_mode().is_halted(), Error::::Halted); - log::info!(target: "snowbridge-inbound-queue", "WOOP"); + log::info!(target: "ethereum-beacon-client", "WOOP"); // submit message to verifier for verification let logf = T::Verifier::verify(&message)?; - log::info!(target: "snowbridge-inbound-queue", "BAR: {:?} {:?}", logf.data.len(), logf.topics.len()); - log::info!(target: "snowbridge-inbound-queue", "BOOZ: {:?}", logf.topics.get(0).unwrap()); + log::info!(target: "ethereum-beacon-client", "BAR: {:?} {:?}", logf.data.len(), logf.topics.len()); + log::info!(target: "ethereum-beacon-client", "BOOZ: {:?}", logf.topics.get(0).unwrap()); // Decode log into an Envelope let envelope = Envelope::try_from(logf).map_err(|_| Error::::InvalidEnvelope)?; diff --git a/parachain/primitives/router/Cargo.toml b/parachain/primitives/router/Cargo.toml index 3a93e709bf..056a33d2ca 100644 --- a/parachain/primitives/router/Cargo.toml +++ b/parachain/primitives/router/Cargo.toml @@ -47,6 +47,7 @@ std = [ "xcm-executor/std", "snowbridge-core/std", "ethabi/std", + "log/std", ] runtime-benchmarks = [ "snowbridge-core/runtime-benchmarks", diff --git a/polkadot-sdk b/polkadot-sdk index ce31f30276..ed481c9c7e 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit ce31f302769f26f61a95efda3c50508cfb0bca46 +Subproject commit ed481c9c7e94b810311cf2bd597b5e5c46724904 diff --git a/web/packages/test/scripts/configure-bridgehub.sh b/web/packages/test/scripts/configure-bridgehub.sh index 83fb369362..c43625d42c 100755 --- a/web/packages/test/scripts/configure-bridgehub.sh +++ b/web/packages/test/scripts/configure-bridgehub.sh @@ -74,7 +74,6 @@ configure_bridgehub() { wait_beacon_chain_ready config_beacon_checkpoint open_hrmp_channels - enable_gateway } if [ -z "${from_start_services:-}" ]; then From 84d2a292fe113f119623feac7ea0037ccfa460bc Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 09:33:42 +0200 Subject: [PATCH 03/20] inbound-queue no longer depends on older legacy ethereum-related crates --- parachain/Cargo.lock | 15 ++++++- .../ethereum-beacon-client/src/impls.rs | 23 +++++----- .../ethereum-beacon-client/src/tests.rs | 15 ++++--- parachain/pallets/inbound-queue/Cargo.toml | 8 ++-- .../pallets/inbound-queue/src/envelope.rs | 44 +++++++++---------- parachain/pallets/inbound-queue/src/lib.rs | 17 +++---- parachain/pallets/inbound-queue/src/test.rs | 29 +++--------- parachain/primitives/core/src/inbound.rs | 39 +++++++++------- 8 files changed, 98 insertions(+), 92 deletions(-) diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 7da754e114..6593791e25 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -85,11 +85,23 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cc0fac0fc16baf1f63f78b47c3d24718f3619b0714076f6a02957d808d52cbef" dependencies = [ + "alloy-rlp-derive", "arrayvec 0.7.2", "bytes", "smol_str", ] +[[package]] +name = "alloy-rlp-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0391754c09fab4eae3404d19d0d297aa1c670c1775ab51d8a5312afeca23157" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "alloy-sol-macro" version = "0.4.2" @@ -3606,6 +3618,8 @@ dependencies = [ name = "snowbridge-inbound-queue" version = "0.1.1" dependencies = [ + "alloy-primitives", + "alloy-rlp", "alloy-sol-types", "frame-benchmarking", "frame-support", @@ -3615,7 +3629,6 @@ dependencies = [ "num-traits", "pallet-balances", "parity-scale-codec", - "rlp", "scale-info", "serde", "snowbridge-beacon-primitives", diff --git a/parachain/pallets/ethereum-beacon-client/src/impls.rs b/parachain/pallets/ethereum-beacon-client/src/impls.rs index 571c0f9f7c..189dc6e93c 100644 --- a/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/parachain/pallets/ethereum-beacon-client/src/impls.rs @@ -2,23 +2,23 @@ // SPDX-FileCopyrightText: 2023 Snowfork use super::*; -use snowbridge_ethereum::{Log, Receipt}; -use sp_runtime::DispatchError; +use snowbridge_core::inbound::VerificationError::{self, *}; +use snowbridge_ethereum::Receipt; impl Verifier for Pallet { /// Verify a message by verifying the existence of the corresponding /// Ethereum log in a block. Returns the log if successful. The execution header containing /// the log should be in the beacon client storage, meaning it has been verified and is an /// ancestor of a finalized beacon block. - fn verify(message: &Message) -> Result { + fn verify(message: &Message) -> Result<(), VerificationError> { log::info!( target: "ethereum-beacon-client", "💫 Verifying message with block hash {}", message.proof.block_hash, ); - let header = >::get(message.proof.block_hash) - .ok_or(Error::::MissingHeader)?; + let header = + >::get(message.proof.block_hash).ok_or(HeaderNotFound)?; let receipt = match Self::verify_receipt_inclusion(header.receipts_root, &message.proof) { Ok(receipt) => receipt, @@ -48,7 +48,7 @@ impl Verifier for Pallet { message.proof.block_hash, err ); - return Err(Error::::DecodeFailed.into()) + return Err(InvalidLog) }, }; @@ -58,7 +58,7 @@ impl Verifier for Pallet { "💫 Event log not found in receipt for transaction at index {} in block {}", message.proof.tx_index, message.proof.block_hash, ); - return Err(Error::::InvalidProof.into()) + return Err(NotFound) } log::info!( @@ -67,7 +67,7 @@ impl Verifier for Pallet { message.proof.block_hash, ); - Ok(log) + Ok(()) } } @@ -77,9 +77,8 @@ impl Pallet { pub fn verify_receipt_inclusion( receipts_root: H256, proof: &Proof, - ) -> Result { - let result = - verify_receipt_proof(receipts_root, &proof.data.1).ok_or(Error::::InvalidProof)?; + ) -> Result { + let result = verify_receipt_proof(receipts_root, &proof.data.1).ok_or(InvalidProof)?; match result { Ok(receipt) => Ok(receipt), @@ -89,7 +88,7 @@ impl Pallet { "💫 Failed to decode transaction receipt: {}", err ); - Err(Error::::InvalidProof.into()) + Err(InvalidProof) }, } } diff --git a/parachain/pallets/ethereum-beacon-client/src/tests.rs b/parachain/pallets/ethereum-beacon-client/src/tests.rs index 32cf0d485d..e4cc7a5435 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -16,7 +16,10 @@ use primitives::{ CompactExecutionHeader, ExecutionHeaderState, Fork, ForkVersions, NextSyncCommitteeUpdate, }; use rand::{thread_rng, Rng}; -use snowbridge_core::{inbound::Verifier, RingBufferMap}; +use snowbridge_core::{ + inbound::{VerificationError, Verifier}, + RingBufferMap, +}; use sp_core::H256; use sp_runtime::DispatchError; @@ -922,7 +925,7 @@ fn verify_message_missing_header() { let message = get_message_verification_payload(); new_tester().execute_with(|| { - assert_err!(EthereumBeaconClient::verify(&message), Error::::MissingHeader); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::HeaderNotFound); }); } @@ -935,7 +938,7 @@ fn verify_message_invalid_proof() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); }); } @@ -948,7 +951,7 @@ fn verify_message_invalid_receipts_root() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); }); } @@ -961,7 +964,7 @@ fn verify_message_invalid_message_data() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::DecodeFailed); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidLog); }); } @@ -974,7 +977,7 @@ fn verify_message_receipt_does_not_contain_log() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), Error::::InvalidProof); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::NotFound); }); } diff --git a/parachain/pallets/inbound-queue/Cargo.toml b/parachain/pallets/inbound-queue/Cargo.toml index 71d0c20730..688d392499 100644 --- a/parachain/pallets/inbound-queue/Cargo.toml +++ b/parachain/pallets/inbound-queue/Cargo.toml @@ -14,9 +14,10 @@ serde = { version = "1.0.188", optional = true } codec = { version = "3.6.1", package = "parity-scale-codec", default-features = false, features = [ "derive" ] } scale-info = { version = "2.9.0", default-features = false, features = [ "derive" ] } hex-literal = { version = "0.4.1", optional = true } -rlp = { version = "0.5.2", default-features = false, optional = true } log = { version = "0.4.20", default-features = false } +alloy-primitives = { version = "0.4.2", default-features = false, features = ["rlp"] } alloy-sol-types = { version = "0.4.2", default-features = false } +alloy-rlp = { version = "0.3.3", default-features = false, features = ["derive"] } num-traits = { version = "0.2.16", default-features = false } frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarking", default-features = false, optional = true } @@ -41,9 +42,7 @@ frame-benchmarking = { path = "../../../polkadot-sdk/substrate/frame/benchmarkin sp-keyring = { path = "../../../polkadot-sdk/substrate/primitives/keyring" } snowbridge-beacon-primitives = { path = "../../primitives/beacon" } snowbridge-ethereum-beacon-client = { path = "../../pallets/ethereum-beacon-client" } - hex-literal = { version = "0.4.1" } -rlp = { version = "0.5.2" } [features] default = ["std"] @@ -52,7 +51,9 @@ std = [ "log/std", "codec/std", "scale-info/std", + "alloy-primitives/std", "alloy-sol-types/std", + "alloy-rlp/std", "frame-support/std", "frame-system/std", "pallet-balances/std", @@ -74,7 +75,6 @@ runtime-benchmarks = [ "frame-support/runtime-benchmarks", "frame-system/runtime-benchmarks", "hex-literal", - "rlp", "snowbridge-beacon-primitives", "xcm-builder/runtime-benchmarks", ] diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index 225d90216d..e12ecf6c0f 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -1,12 +1,20 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork use snowbridge_core::ParaId; -use snowbridge_ethereum::{log::Log, H160}; -use sp_core::{RuntimeDebug, H256}; +use sp_core::{RuntimeDebug, H160, H256}; use sp_std::{convert::TryFrom, prelude::*}; -use alloy_sol_types::{abi::token::WordToken, sol, SolEvent}; +use alloy_primitives::{Address, Bytes, B256}; +use alloy_rlp::RlpDecodable; +use alloy_sol_types::{sol, SolEvent}; + +#[derive(RlpDecodable, RuntimeDebug)] +pub struct Log { + pub address: Address, + pub topics: Vec, + pub data: Bytes, +} sol! { event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); @@ -27,30 +35,22 @@ pub struct Envelope { pub payload: Vec, } -#[derive(Copy, Clone, PartialEq, Eq, RuntimeDebug)] +#[derive(Copy, Clone, RuntimeDebug)] pub struct EnvelopeDecodeError; impl TryFrom for Envelope { type Error = EnvelopeDecodeError; fn try_from(log: Log) -> Result { - let topics: Vec = log - .clone() - .topics - .iter() - .map(|t| WordToken::from(*t.as_fixed_bytes())) - .collect(); - - let event = OutboundMessageAccepted::decode_log(topics, &log.data, true).map_err(|e| { - log::error!(target: "ethereum-beacon-client","FOO {:?}", e); - EnvelopeDecodeError - })?; - - let dest: ParaId = event.destination.saturating_to::().into(); - let nonce = event.nonce; - let message_id = H256::from(event.messageID.as_ref()); - let payload = event.payload; - - Ok(Self { gateway: log.address, dest, nonce, message_id, payload }) + let event = OutboundMessageAccepted::decode_log(log.topics, &log.data, true) + .map_err(|_| EnvelopeDecodeError)?; + + Ok(Self { + gateway: H160::from(log.address.as_ref()), + dest: event.destination.saturating_to::().into(), + nonce: event.nonce, + message_id: H256::from(event.messageID.as_ref()), + payload: event.payload, + }) } } diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index a6d17d11f2..124184c44b 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -36,8 +36,9 @@ pub mod weights; #[cfg(test)] mod test; +use alloy_rlp::Decodable as RlpDecodable; use codec::{Decode, DecodeAll, Encode}; -use envelope::Envelope; +use envelope::{Envelope, Log}; use frame_support::{ traits::{ fungible::{Inspect, Mutate}, @@ -49,7 +50,7 @@ use frame_support::{ use frame_system::ensure_signed; use scale_info::TypeInfo; use snowbridge_core::{ - inbound::{Message, Verifier}, + inbound::{Message, VerificationError, Verifier}, sibling_sovereign_account, BasicOperatingMode, ParaId, }; use snowbridge_router_primitives::{ @@ -156,6 +157,8 @@ pub mod pallet { InvalidAccountConversion, /// Pallet is halted Halted, + /// Message verification error, + Verification(VerificationError), /// XCMP send failure Send(SendError), /// Message conversion error @@ -207,16 +210,14 @@ pub mod pallet { let who = ensure_signed(origin)?; ensure!(!Self::operating_mode().is_halted(), Error::::Halted); - log::info!(target: "ethereum-beacon-client", "WOOP"); - // submit message to verifier for verification - let logf = T::Verifier::verify(&message)?; + T::Verifier::verify(&message).map_err(|e| Error::::Verification(e))?; - log::info!(target: "ethereum-beacon-client", "BAR: {:?} {:?}", logf.data.len(), logf.topics.len()); - log::info!(target: "ethereum-beacon-client", "BOOZ: {:?}", logf.topics.get(0).unwrap()); + let log = Log::decode(&mut message.data.as_slice()) + .map_err(|_| Error::::InvalidEnvelope)?; // Decode log into an Envelope - let envelope = Envelope::try_from(logf).map_err(|_| Error::::InvalidEnvelope)?; + let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope)?; // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == envelope.gateway, Error::::InvalidGateway,); diff --git a/parachain/pallets/inbound-queue/src/test.rs b/parachain/pallets/inbound-queue/src/test.rs index c34c1c8fe3..e7b3224b65 100644 --- a/parachain/pallets/inbound-queue/src/test.rs +++ b/parachain/pallets/inbound-queue/src/test.rs @@ -10,10 +10,9 @@ use frame_support::{ use hex_literal::hex; use snowbridge_beacon_primitives::{Fork, ForkVersions}; use snowbridge_core::{ - inbound::{Message, Proof}, + inbound::{Message, Proof, VerificationError}, ParaId, }; -use snowbridge_ethereum::Log; use snowbridge_router_primitives::inbound::MessageToXcm; use sp_core::{H160, H256}; use sp_keyring::AccountKeyring as Keyring; @@ -24,7 +23,7 @@ use sp_runtime::{ use sp_std::convert::From; use xcm::v3::{prelude::*, MultiAssets, SendXcm}; -use crate::{self as inbound_queue, envelope::Envelope, Error, Event as InboundQueueEvent}; +use crate::{self as inbound_queue, Error, Event as InboundQueueEvent}; type Block = frame_system::mocking::MockBlock; @@ -121,9 +120,8 @@ impl snowbridge_ethereum_beacon_client::Config for Test { pub struct MockVerifier; impl Verifier for MockVerifier { - fn verify(message: &Message) -> Result { - let log: Log = rlp::decode(&message.data).unwrap(); - Ok(log) + fn verify(_: &Message) -> Result<(), VerificationError> { + Ok(()) } } @@ -221,22 +219,6 @@ pub fn new_tester() -> sp_io::TestExternalities { ext } -fn parse_dest(message: Message) -> ParaId { - let log = MockVerifier::verify(&message) - .map_err(|err| { - println!("mock verify: {:?}", err); - err - }) - .unwrap(); - let envelope = Envelope::try_from(log) - .map_err(|err| { - println!("envelope: {:?}", err); - err - }) - .unwrap(); - envelope.dest -} - // dest para is 1000 const OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( " @@ -369,8 +351,7 @@ fn test_submit_with_invalid_nonce() { }; assert_ok!(InboundQueue::submit(origin.clone(), message.clone())); - let event_dest = parse_dest(message.clone()); - let nonce: u64 = >::get(event_dest); + let nonce: u64 = >::get(ParaId::from(1000)); assert_eq!(nonce, 1); // Submit the same again diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index 5e7b10c25b..be179de7fe 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -3,36 +3,45 @@ //! Types for representing inbound messages use codec::{Decode, Encode}; +use frame_support::PalletError; use scale_info::TypeInfo; -use snowbridge_ethereum::Log; use sp_core::H256; -use sp_runtime::{DispatchError, RuntimeDebug}; +use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; /// A trait for verifying inbound messages from Ethereum. -/// -/// This trait should be implemented by runtime modules that wish to provide message verification -/// functionality. pub trait Verifier { - fn verify(message: &Message) -> Result; + fn verify(message: &Message) -> Result<(), VerificationError>; +} + +#[derive(Clone, Encode, Decode, RuntimeDebug, PalletError, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub enum VerificationError { + /// Execution header is missing + HeaderNotFound, + /// Log was not found in the verified transaction receipt + NotFound, + /// Data payload does not decode into a valid Log + InvalidLog, + /// Unable to verify the transaction receipt with the provided proof + InvalidProof, } pub type MessageNonce = u64; -/// A message relayed from Ethereum. -#[derive(PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +/// A bridge message from the Gateway contract on Ethereum +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] pub struct Message { - /// The raw RLP-encoded message data. + /// RLP-encoded event log pub data: Vec, - /// Input to the message verifier + /// Inclusion proof for a transaction receipt containing the event log pub proof: Proof, } -/// Verification input for the message verifier. -/// -/// This data type allows us to support multiple verification schemes. In the near future, -/// A light-client scheme will be added too. -#[derive(PartialEq, Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +/// Inclusion proof for a transaction receipt +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] pub struct Proof { // The block hash of the block in which the receipt was included. pub block_hash: H256, From b0e408e27129dff6fcd049dcfb3e7aa836141b46 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 10:00:41 +0200 Subject: [PATCH 04/20] Use for generating unique message ids --- parachain/pallets/control/src/lib.rs | 15 +-------------- parachain/pallets/control/src/tests.rs | 4 ++-- .../outbound-queue/src/benchmarking.rs | 2 +- parachain/pallets/outbound-queue/src/mock.rs | 6 +++--- .../outbound-queue/src/send_message_impl.rs | 9 +++++++-- parachain/primitives/core/src/outbound.rs | 19 +++++++++++++------ .../primitives/router/src/outbound/mod.rs | 2 +- 7 files changed, 28 insertions(+), 29 deletions(-) diff --git a/parachain/pallets/control/src/lib.rs b/parachain/pallets/control/src/lib.rs index 627ec9ac23..c0417fa400 100644 --- a/parachain/pallets/control/src/lib.rs +++ b/parachain/pallets/control/src/lib.rs @@ -200,10 +200,6 @@ pub mod pallet { #[pallet::getter(fn channels)] pub type Channels = StorageMap<_, Twox64Concat, ParaId, (), OptionQuery>; - /// Generator for a unique message ID - #[pallet::storage] - pub type NextMessageId = StorageValue<_, u64, ValueQuery>; - #[pallet::call] impl Pallet { /// Sends command to the Gateway contract to upgrade itself with a new implementation @@ -433,7 +429,7 @@ pub mod pallet { impl Pallet { /// Send `command` to the Gateway on the channel identified by `origin`. fn send(origin: ParaId, command: Command, pays_fee: PaysFee) -> DispatchResult { - let message = Message { id: Self::alloc_message_id(), origin, command }; + let message = Message { id: None, origin, command }; let (ticket, fee) = T::OutboundQueue::validate(&message).map_err(|err| Error::::Send(err))?; @@ -477,14 +473,5 @@ pub mod pallet { }); Ok(()) } - - // Allocate a unique id for a message. Used in the implementation of SendMessage,. - pub(crate) fn alloc_message_id() -> H256 { - NextMessageId::::mutate(|next_message_id| { - *next_message_id = next_message_id.saturating_add(1) - }); - let next_message_id = NextMessageId::::get(); - sp_io::hashing::blake2_256(&(next_message_id.encode())).into() - } } } diff --git a/parachain/pallets/control/src/tests.rs b/parachain/pallets/control/src/tests.rs index ba8b77f995..10be9b3a65 100644 --- a/parachain/pallets/control/src/tests.rs +++ b/parachain/pallets/control/src/tests.rs @@ -521,7 +521,7 @@ fn charge_fee_for_create_agent() { assert_ok!(EthereumControl::create_agent(origin.clone())); // assert sovereign_balance decreased by (fee.base_fee + fee.delivery_fee) let message = Message { - id: H256::zero(), + id: None, origin: para_id.into(), command: Command::CreateAgent { agent_id }, }; @@ -558,7 +558,7 @@ fn charge_fee_for_transfer_native_from_agent() { let sovereign_balance_before = Balances::balance(&sovereign_account); assert_ok!(EthereumControl::transfer_native_from_agent(origin.clone(), recipient, amount)); let message = Message { - id: H256::zero(), + id: None, origin: para_id.into(), command: Command::TransferNativeFromAgent { agent_id, recipient, amount }, }; diff --git a/parachain/pallets/outbound-queue/src/benchmarking.rs b/parachain/pallets/outbound-queue/src/benchmarking.rs index 921507425f..4ec2910ece 100644 --- a/parachain/pallets/outbound-queue/src/benchmarking.rs +++ b/parachain/pallets/outbound-queue/src/benchmarking.rs @@ -21,7 +21,7 @@ mod benchmarks { #[benchmark] fn do_process_message() -> Result<(), BenchmarkError> { let enqueued_message = QueuedMessage { - id: H256::zero(), + id: None, origin: 1000.into(), command: Command::Upgrade { impl_address: H160::zero(), diff --git a/parachain/pallets/outbound-queue/src/mock.rs b/parachain/pallets/outbound-queue/src/mock.rs index 794c953faa..d817261068 100644 --- a/parachain/pallets/outbound-queue/src/mock.rs +++ b/parachain/pallets/outbound-queue/src/mock.rs @@ -127,7 +127,7 @@ where T: Config, { Message { - id: H256::zero(), + id: None, origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -143,7 +143,7 @@ where T: Config, { Message { - id: H256::zero(), + id: None, origin: OwnParaIdOf::::get(), command: Command::Upgrade { impl_address: H160::zero(), @@ -158,7 +158,7 @@ where pub fn mock_message(sibling_para_id: u32) -> Message { Message { - id: H256::zero(), + id: None, origin: sibling_para_id.into(), command: Command::AgentExecute { agent_id: Default::default(), diff --git a/parachain/pallets/outbound-queue/src/send_message_impl.rs b/parachain/pallets/outbound-queue/src/send_message_impl.rs index 080bde21be..9dacf2c17f 100644 --- a/parachain/pallets/outbound-queue/src/send_message_impl.rs +++ b/parachain/pallets/outbound-queue/src/send_message_impl.rs @@ -6,6 +6,7 @@ use frame_support::{ traits::{EnqueueMessage, Get}, CloneNoBound, PartialEqNoBound, RuntimeDebugNoBound, }; +use frame_system::unique; use snowbridge_core::outbound::{ AggregateMessageOrigin, ExportOrigin, Fee, Message, QueuedMessage, SendError, SendMessage, Ticket as TicketTrait, VersionedQueuedMessage, @@ -52,10 +53,14 @@ where SendError::MessageTooLarge ); + // Generate a unique message id unless one is provided + let message_id: H256 = + message.id.unwrap_or_else(|| unique((message.origin, &message.command)).into()); + let fee = Self::calculate_fee(&message.command); let queued_message: VersionedQueuedMessage = QueuedMessage { - id: message.id, + id: message_id, origin: message.origin, command: message.command.clone(), } @@ -63,7 +68,7 @@ where // The whole message should not be too large let encoded = queued_message.encode().try_into().map_err(|_| SendError::MessageTooLarge)?; - let ticket = Ticket { message_id: message.id, origin: message.origin, message: encoded }; + let ticket = Ticket { message_id, origin: message.origin, message: encoded }; Ok((ticket, fee)) } diff --git a/parachain/primitives/core/src/outbound.rs b/parachain/primitives/core/src/outbound.rs index 57723a17f2..1afafec13f 100644 --- a/parachain/primitives/core/src/outbound.rs +++ b/parachain/primitives/core/src/outbound.rs @@ -38,12 +38,17 @@ mod v1 { use sp_core::{RuntimeDebug, H160, H256, U256}; use sp_std::{borrow::ToOwned, vec, vec::Vec}; - /// A message which can be accepted by the [`OutboundQueue`] + /// A message which can be accepted by implementations of [`SendMessage`] #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct Message { - /// ID for this message. One will be automatically generated if not provided - pub id: H256, + /// ID for this message. One will be automatically generated if not provided. + /// + /// When this message is created from an XCM message, the ID should be extracted + /// from the `SetTopic` instruction. + /// + /// The ID plays no role in bridge consensus, and is purely meant for message tracing. + pub id: Option, /// The parachain from which the message originated pub origin: ParaId, /// The stable ID for a receiving gateway contract @@ -57,7 +62,7 @@ mod v1 { } /// A command which is executable by the Gateway contract on Ethereum - #[derive(Encode, Decode, TypeInfo, Clone, RuntimeDebug)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub enum Command { /// Execute a sub-command within an agent for a consensus system in Polkadot @@ -177,7 +182,8 @@ mod v1 { /// Representation of a call to the initializer of an implementation contract. /// The initializer has the following ABI signature: `initialize(bytes)`. - #[derive(Encode, Decode, TypeInfo, PartialEq, Clone, RuntimeDebug)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + #[cfg_attr(feature = "std", derive(PartialEq))] pub struct Initializer { /// ABI-encoded params of type `bytes` to pass to the initializer pub params: Vec, @@ -186,7 +192,8 @@ mod v1 { } /// A Sub-command executable within an agent - #[derive(Encode, Decode, Clone, PartialEq, RuntimeDebug, TypeInfo)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] + #[cfg_attr(feature = "std", derive(PartialEq))] pub enum AgentExecuteCommand { /// Transfer ERC20 tokens TransferToken { diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index 1123d29231..7c2024649a 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -118,7 +118,7 @@ where }; let outbound_message = Message { - id: topic_id.into(), + id: Some(topic_id.into()), origin: para_id.into(), command: Command::AgentExecute { agent_id, command: agent_execute_command }, }; From 55787d9d8154525d3287181bfa2fd6f8b9979280 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 11:58:39 +0200 Subject: [PATCH 05/20] foo --- parachain/Cargo.lock | 1 - .../ethereum-beacon-client/src/impls.rs | 44 +++++++++---------- .../pallets/inbound-queue/src/envelope.rs | 18 +++----- parachain/pallets/inbound-queue/src/lib.rs | 16 +++---- parachain/primitives/core/Cargo.toml | 2 - parachain/primitives/core/src/inbound.rs | 17 +++++-- polkadot-sdk | 2 +- 7 files changed, 49 insertions(+), 51 deletions(-) diff --git a/parachain/Cargo.lock b/parachain/Cargo.lock index 6593791e25..96b3859588 100644 --- a/parachain/Cargo.lock +++ b/parachain/Cargo.lock @@ -3551,7 +3551,6 @@ dependencies = [ "scale-info", "serde", "snowbridge-beacon-primitives", - "snowbridge-ethereum", "sp-arithmetic", "sp-core", "sp-runtime", diff --git a/parachain/pallets/ethereum-beacon-client/src/impls.rs b/parachain/pallets/ethereum-beacon-client/src/impls.rs index 189dc6e93c..15eeed93c8 100644 --- a/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/parachain/pallets/ethereum-beacon-client/src/impls.rs @@ -2,7 +2,10 @@ // SPDX-FileCopyrightText: 2023 Snowfork use super::*; -use snowbridge_core::inbound::VerificationError::{self, *}; +use snowbridge_core::inbound::{ + VerificationError::{self, *}, + *, +}; use snowbridge_ethereum::Receipt; impl Verifier for Pallet { @@ -10,23 +13,22 @@ impl Verifier for Pallet { /// Ethereum log in a block. Returns the log if successful. The execution header containing /// the log should be in the beacon client storage, meaning it has been verified and is an /// ancestor of a finalized beacon block. - fn verify(message: &Message) -> Result<(), VerificationError> { + fn verify(event_log: &Log, proof: &Proof) -> Result<(), VerificationError> { log::info!( target: "ethereum-beacon-client", "💫 Verifying message with block hash {}", - message.proof.block_hash, + proof.block_hash, ); - let header = - >::get(message.proof.block_hash).ok_or(HeaderNotFound)?; + let header = >::get(proof.block_hash).ok_or(HeaderNotFound)?; - let receipt = match Self::verify_receipt_inclusion(header.receipts_root, &message.proof) { + let receipt = match Self::verify_receipt_inclusion(header.receipts_root, proof) { Ok(receipt) => receipt, Err(err) => { log::error!( target: "ethereum-beacon-client", "💫 Verification of receipt inclusion failed for block {}: {:?}", - message.proof.block_hash, + proof.block_hash, err ); return Err(err) @@ -36,27 +38,25 @@ impl Verifier for Pallet { log::trace!( target: "ethereum-beacon-client", "💫 Verified receipt inclusion for transaction at index {} in block {}", - message.proof.tx_index, message.proof.block_hash, + proof.tx_index, proof.block_hash, ); - let log = match rlp::decode(&message.data) { - Ok(log) => log, - Err(err) => { - log::error!( - target: "ethereum-beacon-client", - "💫 RLP log decoded failed {}: {:?}", - message.proof.block_hash, - err - ); - return Err(InvalidLog) - }, + if event_log.topics.len() > MAX_LOG_TOPICS { + return Err(InvalidLog) + } + + // Convert snowbridge_core::inbound::Log to snowbridge_ethereum::Log. + let event_log = snowbridge_ethereum::Log { + address: event_log.address, + topics: event_log.topics.clone(), + data: event_log.data.clone(), }; - if !receipt.contains_log(&log) { + if !receipt.contains_log(&event_log) { log::error!( target: "ethereum-beacon-client", "💫 Event log not found in receipt for transaction at index {} in block {}", - message.proof.tx_index, message.proof.block_hash, + proof.tx_index, proof.block_hash, ); return Err(NotFound) } @@ -64,7 +64,7 @@ impl Verifier for Pallet { log::info!( target: "ethereum-beacon-client", "💫 Receipt verification successful for {}", - message.proof.block_hash, + proof.block_hash, ); Ok(()) diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index e12ecf6c0f..0e2b0f8753 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -1,21 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 // SPDX-FileCopyrightText: 2023 Snowfork -use snowbridge_core::ParaId; +use snowbridge_core::{inbound::Log, ParaId}; use sp_core::{RuntimeDebug, H160, H256}; use sp_std::{convert::TryFrom, prelude::*}; -use alloy_primitives::{Address, Bytes, B256}; -use alloy_rlp::RlpDecodable; +use alloy_primitives::B256; use alloy_sol_types::{sol, SolEvent}; -#[derive(RlpDecodable, RuntimeDebug)] -pub struct Log { - pub address: Address, - pub topics: Vec, - pub data: Bytes, -} - sol! { event OutboundMessageAccepted(uint256 indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); } @@ -42,11 +34,13 @@ impl TryFrom for Envelope { type Error = EnvelopeDecodeError; fn try_from(log: Log) -> Result { - let event = OutboundMessageAccepted::decode_log(log.topics, &log.data, true) + let topics: Vec = log.topics.iter().map(|x| B256::from_slice(x.as_ref())).collect(); + + let event = OutboundMessageAccepted::decode_log(topics, &log.data, true) .map_err(|_| EnvelopeDecodeError)?; Ok(Self { - gateway: H160::from(log.address.as_ref()), + gateway: H160::from(log.address), dest: event.destination.saturating_to::().into(), nonce: event.nonce, message_id: H256::from(event.messageID.as_ref()), diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index 124184c44b..b16c887339 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -36,9 +36,8 @@ pub mod weights; #[cfg(test)] mod test; -use alloy_rlp::Decodable as RlpDecodable; use codec::{Decode, DecodeAll, Encode}; -use envelope::{Envelope, Log}; +use envelope::Envelope; use frame_support::{ traits::{ fungible::{Inspect, Mutate}, @@ -50,7 +49,7 @@ use frame_support::{ use frame_system::ensure_signed; use scale_info::TypeInfo; use snowbridge_core::{ - inbound::{Message, VerificationError, Verifier}, + inbound::{Log, Message, VerificationError, Verifier}, sibling_sovereign_account, BasicOperatingMode, ParaId, }; use snowbridge_router_primitives::{ @@ -211,13 +210,12 @@ pub mod pallet { ensure!(!Self::operating_mode().is_halted(), Error::::Halted); // submit message to verifier for verification - T::Verifier::verify(&message).map_err(|e| Error::::Verification(e))?; + T::Verifier::verify(&message.data, &message.proof) + .map_err(|e| Error::::Verification(e))?; - let log = Log::decode(&mut message.data.as_slice()) - .map_err(|_| Error::::InvalidEnvelope)?; - - // Decode log into an Envelope - let envelope = Envelope::try_from(log).map_err(|_| Error::::InvalidEnvelope)?; + // Decode event log into an Envelope + let envelope = + Envelope::try_from(message.data).map_err(|_| Error::::InvalidEnvelope)?; // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == envelope.gateway, Error::::InvalidGateway,); diff --git a/parachain/primitives/core/Cargo.toml b/parachain/primitives/core/Cargo.toml index fb8938ad9e..3e78750a7b 100644 --- a/parachain/primitives/core/Cargo.toml +++ b/parachain/primitives/core/Cargo.toml @@ -8,7 +8,6 @@ edition = "2021" serde = { version = "1.0.188", optional = true, features = [ "derive", "alloc" ], default-features = false } codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false } scale-info = { version = "2.9.0", default-features = false, features = [ "derive" ] } -snowbridge-ethereum = { path = "../ethereum", default-features = false } polkadot-parachain-primitives = { path = "../../../polkadot-sdk/polkadot/parachain", default-features = false } xcm = { package = "staging-xcm", path = "../../../polkadot-sdk/polkadot/xcm", default-features = false } @@ -39,7 +38,6 @@ std = [ "sp-std/std", "sp-core/std", "sp-runtime/std", - "snowbridge-ethereum/std", "snowbridge-beacon-primitives/std", "xcm/std", "ethabi/std", diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index be179de7fe..4b5c71fdb8 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -5,13 +5,13 @@ use codec::{Decode, Encode}; use frame_support::PalletError; use scale_info::TypeInfo; -use sp_core::H256; +use sp_core::{H160, H256}; use sp_runtime::RuntimeDebug; use sp_std::vec::Vec; /// A trait for verifying inbound messages from Ethereum. pub trait Verifier { - fn verify(message: &Message) -> Result<(), VerificationError>; + fn verify(event: &Log, proof: &Proof) -> Result<(), VerificationError>; } #[derive(Clone, Encode, Decode, RuntimeDebug, PalletError, TypeInfo)] @@ -33,12 +33,21 @@ pub type MessageNonce = u64; #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct Message { - /// RLP-encoded event log - pub data: Vec, + /// Event log + pub data: Log, /// Inclusion proof for a transaction receipt containing the event log pub proof: Proof, } +/// Event log +#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] +#[cfg_attr(feature = "std", derive(PartialEq))] +pub struct Log { + pub address: H160, + pub topics: Vec, + pub data: Vec, +} + /// Inclusion proof for a transaction receipt #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] diff --git a/polkadot-sdk b/polkadot-sdk index ed481c9c7e..0b22697c04 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit ed481c9c7e94b810311cf2bd597b5e5c46724904 +Subproject commit 0b22697c04cb30d86fc618d3217d771b58ffd734 From 6f0eecb9d5383dd54c7a3e200704d94b20e59467 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 12:29:26 +0200 Subject: [PATCH 06/20] Bump polkadot-sdk --- polkadot-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot-sdk b/polkadot-sdk index f4e542d9b6..1adaaee513 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit f4e542d9b663aa6c5cc1b67bf59f8373d64db844 +Subproject commit 1adaaee51314dc7747442b1179a781ffb648d1d0 From 211895023a143174dd2fa1b385d304681e96d4e4 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 15:36:23 +0200 Subject: [PATCH 07/20] revert some changes that caused tests to fail --- parachain/primitives/core/src/inbound.rs | 6 ++---- parachain/primitives/core/src/outbound.rs | 5 ++--- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index be179de7fe..8f3d6d6332 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -30,8 +30,7 @@ pub enum VerificationError { pub type MessageNonce = u64; /// A bridge message from the Gateway contract on Ethereum -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -#[cfg_attr(feature = "std", derive(PartialEq))] +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Message { /// RLP-encoded event log pub data: Vec, @@ -40,8 +39,7 @@ pub struct Message { } /// Inclusion proof for a transaction receipt -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -#[cfg_attr(feature = "std", derive(PartialEq))] +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Proof { // The block hash of the block in which the receipt was included. pub block_hash: H256, diff --git a/parachain/primitives/core/src/outbound.rs b/parachain/primitives/core/src/outbound.rs index 9b1c741906..4d3f78ca31 100644 --- a/parachain/primitives/core/src/outbound.rs +++ b/parachain/primitives/core/src/outbound.rs @@ -182,8 +182,7 @@ mod v1 { /// Representation of a call to the initializer of an implementation contract. /// The initializer has the following ABI signature: `initialize(bytes)`. - #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] - #[cfg_attr(feature = "std", derive(PartialEq))] + #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Initializer { /// ABI-encoded params of type `bytes` to pass to the initializer pub params: Vec, @@ -230,7 +229,7 @@ mod v1 { } /// Message which is awaiting processing in the MessageQueue pallet - #[derive(Encode, Decode, Clone, RuntimeDebug, TypeInfo)] + #[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] #[cfg_attr(feature = "std", derive(PartialEq))] pub struct QueuedMessage { /// Message ID From 75ccfa7bedefa81d2565526ca2a528e11c5ecddb Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 20:15:50 +0200 Subject: [PATCH 08/20] review feedback --- parachain/pallets/ethereum-beacon-client/src/impls.rs | 2 +- parachain/pallets/ethereum-beacon-client/src/tests.rs | 2 +- parachain/primitives/core/src/inbound.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/parachain/pallets/ethereum-beacon-client/src/impls.rs b/parachain/pallets/ethereum-beacon-client/src/impls.rs index 189dc6e93c..35b2e287de 100644 --- a/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/parachain/pallets/ethereum-beacon-client/src/impls.rs @@ -58,7 +58,7 @@ impl Verifier for Pallet { "💫 Event log not found in receipt for transaction at index {} in block {}", message.proof.tx_index, message.proof.block_hash, ); - return Err(NotFound) + return Err(LogNotFound) } log::info!( diff --git a/parachain/pallets/ethereum-beacon-client/src/tests.rs b/parachain/pallets/ethereum-beacon-client/src/tests.rs index e4cc7a5435..95a7c38229 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -977,7 +977,7 @@ fn verify_message_receipt_does_not_contain_log() { new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::NotFound); + assert_err!(EthereumBeaconClient::verify(&message), VerificationError::LogNotFound); }); } diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index 8f3d6d6332..bc28c7e3bb 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -20,7 +20,7 @@ pub enum VerificationError { /// Execution header is missing HeaderNotFound, /// Log was not found in the verified transaction receipt - NotFound, + LogNotFound, /// Data payload does not decode into a valid Log InvalidLog, /// Unable to verify the transaction receipt with the provided proof From 1186e92b12b0ab8c34a3e16370d36a3fe81c3f55 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 20:25:28 +0200 Subject: [PATCH 09/20] more review feedback --- contracts/src/Assets.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/src/Assets.sol b/contracts/src/Assets.sol index 3f04a3ba6e..b53a6f6ff5 100644 --- a/contracts/src/Assets.sol +++ b/contracts/src/Assets.sol @@ -9,7 +9,7 @@ import {SafeTokenTransferFrom} from "./utils/SafeTransfer.sol"; import {AssetsStorage} from "./storage/AssetsStorage.sol"; import {SubstrateTypes} from "./SubstrateTypes.sol"; -import {ParaID, Config, Channel} from "./Types.sol"; +import {ParaID, Config} from "./Types.sol"; import {Address} from "./utils/Address.sol"; /// @title Library for implementing Ethereum->Polkadot ERC20 transfers. From 67a66b1a0f75f9e84f4fa01481c674f818d3dc9f Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 21:20:57 +0200 Subject: [PATCH 10/20] Update polkadot-sdk --- polkadot-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot-sdk b/polkadot-sdk index 1adaaee513..f7fbba7532 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit 1adaaee51314dc7747442b1179a781ffb648d1d0 +Subproject commit f7fbba753247de67d36af870b2c69b8f2efc629a From 884355dad1a9e9d864805290159522f9d6b61809 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Wed, 8 Nov 2023 21:22:34 +0200 Subject: [PATCH 11/20] remove obsolete code --- contracts/src/interfaces/IGateway.sol | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/src/interfaces/IGateway.sol b/contracts/src/interfaces/IGateway.sol index aaf8e8ee1e..26f565983b 100644 --- a/contracts/src/interfaces/IGateway.sol +++ b/contracts/src/interfaces/IGateway.sol @@ -16,9 +16,6 @@ interface IGateway { // Emitted when an outbound message has been accepted for delivery to a Polkadot parachain event OutboundMessageAccepted(ParaID indexed destination, uint64 nonce, bytes32 indexed messageID, bytes payload); - // Emitted when an dispatched inbound message or an accepted outbound message are associated with one or more topic IDs - event Topic(bytes32 topicID); - // Emitted when an agent has been created for a consensus system on Polkadot event AgentCreated(bytes32 agentID, address agent); From 2c303b221fbb063b50d8a44f37af310409814e31 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 10:32:13 +0200 Subject: [PATCH 12/20] Remove misc whitespace --- web/packages/test/scripts/set-env.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/web/packages/test/scripts/set-env.sh b/web/packages/test/scripts/set-env.sh index 00d1e23fc5..21585af512 100755 --- a/web/packages/test/scripts/set-env.sh +++ b/web/packages/test/scripts/set-env.sh @@ -82,7 +82,6 @@ export DEFAULT_FEE="${ETH_DEFAULT_FEE:-1}" export CREATE_CALL_INDEX="${ETH_CREATE_CALL_INDEX:-0x3500}" - export REGISTER_NATIVE_TOKEN_FEE="${ETH_REGISTER_NATIVE_TOKEN_FEE:-0}" export SEND_NATIVE_TOKEN_FEE="${ETH_SEND_NATIVE_TOKEN_FEE:-0}" From 2fd977717957b20660c9261083a5f3cca76c0595 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 10:44:47 +0200 Subject: [PATCH 13/20] Add back tests I hastily removed --- .../primitives/router/src/outbound/mod.rs | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/parachain/primitives/router/src/outbound/mod.rs b/parachain/primitives/router/src/outbound/mod.rs index 1e91ae1fc3..80e61dae5c 100644 --- a/parachain/primitives/router/src/outbound/mod.rs +++ b/parachain/primitives/router/src/outbound/mod.rs @@ -756,6 +756,71 @@ mod tests { assert_eq!(result, Ok((expected_payload, [0; 32]))); } + #[test] + fn xcm_converter_convert_with_fees_less_than_reserve_yields_success() { + let network = BridgedNetwork::get(); + + let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); + let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); + + let asset_location = X1(AccountKey20 { network: None, key: token_address }).into(); + let fee_asset = MultiAsset { id: Concrete(asset_location), fun: Fungible(500) }; + + let assets: MultiAssets = + vec![MultiAsset { id: Concrete(asset_location), fun: Fungible(1000) }].into(); + + let filter: MultiAssetFilter = assets.clone().into(); + + let message: Xcm<()> = vec![ + WithdrawAsset(assets.clone()), + ClearOrigin, + BuyExecution { fees: fee_asset, weight_limit: Unlimited }, + DepositAsset { + assets: filter, + beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + }, + SetTopic([0; 32]), + ] + .into(); + let mut converter = XcmConverter::new(&message, &network); + let expected_payload = AgentExecuteCommand::TransferToken { + token: token_address.into(), + recipient: beneficiary_address.into(), + amount: 1000, + }; + let result = converter.convert(); + assert_eq!(result, Ok((expected_payload, [0; 32]))); + } + + #[test] + fn xcm_converter_convert_without_set_topic_yields_set_topic_expected() { + let network = BridgedNetwork::get(); + + let token_address: [u8; 20] = hex!("1000000000000000000000000000000000000000"); + let beneficiary_address: [u8; 20] = hex!("2000000000000000000000000000000000000000"); + + let assets: MultiAssets = vec![MultiAsset { + id: Concrete(X1(AccountKey20 { network: None, key: token_address }).into()), + fun: Fungible(1000), + }] + .into(); + let filter: MultiAssetFilter = assets.clone().into(); + + let message: Xcm<()> = vec![ + WithdrawAsset(assets.clone()), + BuyExecution { fees: assets.get(0).unwrap().clone(), weight_limit: Unlimited }, + DepositAsset { + assets: filter, + beneficiary: X1(AccountKey20 { network: None, key: beneficiary_address }).into(), + }, + ClearTopic, + ] + .into(); + let mut converter = XcmConverter::new(&message, &network); + let result = converter.convert(); + assert_eq!(result.err(), Some(XcmConverterError::SetTopicExpected)); + } + #[test] fn xcm_converter_convert_with_partial_message_yields_unexpected_end_of_xcm() { let network = BridgedNetwork::get(); From 468b6a1f91b985296f26bf837a011bcb818f1584 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 15:54:27 +0200 Subject: [PATCH 14/20] Make everything work E2E --- .../ethereum-beacon-client/src/impls.rs | 4 +- .../pallets/ethereum-beacon-client/src/lib.rs | 5 +- .../ethereum-beacon-client/src/mock.rs | 22 ++- .../ethereum-beacon-client/src/tests.rs | 57 +++++--- .../src/benchmarking/fixtures.rs | 12 +- parachain/pallets/inbound-queue/src/lib.rs | 6 +- parachain/pallets/inbound-queue/src/test.rs | 85 +++++++---- parachain/primitives/core/src/inbound.rs | 27 +++- polkadot-sdk | 2 +- relayer/chain/ethereum/message.go | 20 ++- relayer/chain/parachain/message.go | 10 +- relayer/contracts/gateway.go | 136 +----------------- relayer/go.mod | 2 +- relayer/go.sum | 31 ++++ smoketest/tests/register_token.rs | 23 ++- 15 files changed, 220 insertions(+), 222 deletions(-) diff --git a/parachain/pallets/ethereum-beacon-client/src/impls.rs b/parachain/pallets/ethereum-beacon-client/src/impls.rs index 50fefa4ee2..7e72b12631 100644 --- a/parachain/pallets/ethereum-beacon-client/src/impls.rs +++ b/parachain/pallets/ethereum-beacon-client/src/impls.rs @@ -41,9 +41,7 @@ impl Verifier for Pallet { proof.tx_index, proof.block_hash, ); - if event_log.topics.len() > MAX_LOG_TOPICS { - return Err(InvalidLog) - } + event_log.validate().map_err(|_| InvalidLog)?; // Convert snowbridge_core::inbound::Log to snowbridge_ethereum::Log. let event_log = snowbridge_ethereum::Log { diff --git a/parachain/pallets/ethereum-beacon-client/src/lib.rs b/parachain/pallets/ethereum-beacon-client/src/lib.rs index 9c0d435624..c140452aba 100644 --- a/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/parachain/pallets/ethereum-beacon-client/src/lib.rs @@ -43,10 +43,7 @@ use primitives::{ CompactBeaconState, CompactExecutionHeader, ExecutionHeaderState, ForkData, ForkVersion, ForkVersions, PublicKeyPrepared, SigningData, }; -use snowbridge_core::{ - inbound::{Message, Proof, Verifier}, - BasicOperatingMode, RingBufferMap, -}; +use snowbridge_core::{BasicOperatingMode, RingBufferMap}; use sp_core::H256; use sp_std::prelude::*; pub use weights::WeightInfo; diff --git a/parachain/pallets/ethereum-beacon-client/src/mock.rs b/parachain/pallets/ethereum-beacon-client/src/mock.rs index 78e71833be..1addccf790 100644 --- a/parachain/pallets/ethereum-beacon-client/src/mock.rs +++ b/parachain/pallets/ethereum-beacon-client/src/mock.rs @@ -14,7 +14,7 @@ pub mod minimal { use crate::config; use hex_literal::hex; use primitives::CompactExecutionHeader; - use snowbridge_core::inbound::{Message, Proof}; + use snowbridge_core::inbound::{Log, Proof}; use sp_runtime::BuildStorage; use std::{fs::File, path::PathBuf}; @@ -141,10 +141,18 @@ pub mod minimal { load_fixture("next-finalized-header-update.minimal.json").unwrap() } - pub fn get_message_verification_payload() -> Message { - Message { - data: hex!("f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").to_vec(), - proof: Proof { + pub fn get_message_verification_payload() -> (Log, Proof) { + ( + Log { + address: hex!("ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0").into(), + topics: vec![ + hex!("1b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ad").into(), + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + hex!("0000000000000000000000000000000000000000000000000000000000000001").into(), + ], + data: hex!("0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000").into(), + }, + Proof { block_hash: hex!("05aaa60b0f27cce9e71909508527264b77ee14da7b5bf915fcc4e32715333213").into(), tx_index: 0, data: (vec![ @@ -156,8 +164,8 @@ pub mod minimal { hex!("f851a0b9890f91ca0d77aa2a4adfaf9b9e40c94cac9e638b6d9797923865872944b646a060a634b9280e3a23fb63375e7bbdd9ab07fd379ab6a67e2312bbc112195fa358808080808080808080808080808080").to_vec(), hex!("f9030820b9030402f90300018301d6e2b9010000000000000800000000000020040008000000000000000000000000400000008000000000000000000000000000000000000000000000000000000000042010000000001000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000002000000000000000000000000200000000000000200000000000100000000040000001000200008000000000000200000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000f901f5f87a942ffa5ecdbe006d30397c7636d3e015eee251369ff842a0c965575a00553e094ca7c5d14f02e107c258dda06867cbf9e0e69f80e71bbcc1a000000000000000000000000000000000000000000000000000000000000003e8a000000000000000000000000000000000000000000000000000000000000003e8f9011c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000001b8a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004b000f000000000000000100d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec701345772617070656420457468657210574554481235003511000000000000000000000000000000000000000000f858948cf6147918a5cbb672703f879f385036f8793a24e1a01449abf21e49fd025f33495e77f7b1461caefdd3d4bb646424a3f445c4576a5ba0000000000000000000000000440edffa1352b13227e8ee646f3ea37456dec701").to_vec(), ]), - }, - } + } + ) } pub fn get_message_verification_header() -> CompactExecutionHeader { diff --git a/parachain/pallets/ethereum-beacon-client/src/tests.rs b/parachain/pallets/ethereum-beacon-client/src/tests.rs index 95a7c38229..112a7e0f83 100644 --- a/parachain/pallets/ethereum-beacon-client/src/tests.rs +++ b/parachain/pallets/ethereum-beacon-client/src/tests.rs @@ -911,73 +911,88 @@ fn submit_execution_header_not_finalized() { #[test] fn verify_message() { let header = get_message_verification_header(); - let message = get_message_verification_payload(); - let block_hash = message.proof.block_hash; + let (event_log, proof) = get_message_verification_payload(); + let block_hash = proof.block_hash; new_tester().execute_with(|| { >::insert(block_hash, header); - assert_ok!(EthereumBeaconClient::verify(&message)); + assert_ok!(EthereumBeaconClient::verify(&event_log, &proof)); }); } #[test] fn verify_message_missing_header() { - let message = get_message_verification_payload(); + let (event_log, proof) = get_message_verification_payload(); new_tester().execute_with(|| { - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::HeaderNotFound); + assert_err!( + EthereumBeaconClient::verify(&event_log, &proof), + VerificationError::HeaderNotFound + ); }); } #[test] fn verify_message_invalid_proof() { let header = get_message_verification_header(); - let mut message = get_message_verification_payload(); - message.proof.data.1[0] = TEST_HASH.into(); - let block_hash = message.proof.block_hash; + let (event_log, mut proof) = get_message_verification_payload(); + proof.data.1[0] = TEST_HASH.into(); + let block_hash = proof.block_hash; new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); + assert_err!( + EthereumBeaconClient::verify(&event_log, &proof), + VerificationError::InvalidProof + ); }); } #[test] fn verify_message_invalid_receipts_root() { let mut header = get_message_verification_header(); - let message = get_message_verification_payload(); - let block_hash = message.proof.block_hash; + let (event_log, proof) = get_message_verification_payload(); + let block_hash = proof.block_hash; header.receipts_root = TEST_HASH.into(); new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidProof); + assert_err!( + EthereumBeaconClient::verify(&event_log, &proof), + VerificationError::InvalidProof + ); }); } #[test] -fn verify_message_invalid_message_data() { +fn verify_message_invalid_log() { let header = get_message_verification_header(); - let mut message = get_message_verification_payload(); - let block_hash = message.proof.block_hash; - message.data = TEST_HASH.into(); + let (mut event_log, proof) = get_message_verification_payload(); + let block_hash = proof.block_hash; + event_log.topics = vec![H256::zero(); 10]; new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::InvalidLog); + assert_err!( + EthereumBeaconClient::verify(&event_log, &proof), + VerificationError::InvalidLog + ); }); } #[test] fn verify_message_receipt_does_not_contain_log() { let header = get_message_verification_header(); - let mut message = get_message_verification_payload(); - let block_hash = message.proof.block_hash; - message.data = hex!("f9013c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000002b8c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000068000f000000000000000101d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec70100000101001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0000e8890423c78a0000000000000000000000000000000000000000000000000000000000000000").to_vec(); + let (mut event_log, proof) = get_message_verification_payload(); + let block_hash = proof.block_hash; + event_log.data = hex!("f9013c94ee9170abfbf9421ad6dd07f6bdec9d89f2b581e0f863a01b11dcf133cc240f682dab2d3a8e4cd35c5da8c9cf99adac4336f8512584c5ada000000000000000000000000000000000000000000000000000000000000003e8a00000000000000000000000000000000000000000000000000000000000000002b8c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000068000f000000000000000101d184c103f7acc340847eee82a0b909e3358bc28d440edffa1352b13227e8ee646f3ea37456dec70100000101001cbd2d43530a44705ad088af313e18f80b53ef16b36177cd4b77b846f2a5f07c0000e8890423c78a0000000000000000000000000000000000000000000000000000000000000000").to_vec(); new_tester().execute_with(|| { >::insert(block_hash, header); - assert_err!(EthereumBeaconClient::verify(&message), VerificationError::LogNotFound); + assert_err!( + EthereumBeaconClient::verify(&event_log, &proof), + VerificationError::LogNotFound + ); }); } diff --git a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs index 11da799df8..cb4b77310f 100644 --- a/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs +++ b/parachain/pallets/inbound-queue/src/benchmarking/fixtures.rs @@ -1,6 +1,6 @@ use hex_literal::hex; use snowbridge_beacon_primitives::CompactExecutionHeader; -use snowbridge_core::inbound::{Message, Proof}; +use snowbridge_core::inbound::{Log, Message, Proof}; use sp_std::vec; pub struct InboundQueueTest { @@ -17,7 +17,15 @@ pub fn make_create_message() -> InboundQueueTest { receipts_root: hex!("0115ab735d37c5e4cdb0374d8bb547c6dd6ccaa996d996d1eabc5399a719219e").into(), }, message: Message { - data: hex!("f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").to_vec(), + event_log: Log { + address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), + topics: vec![ + hex!("5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169").into(), + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + hex!("afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640f").into(), + ], + data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").into(), + }, proof: Proof { block_hash: hex!("5f465744c166e9d10dc0031942a59ff82b640053253da517a1b576afdadb0363").into(), tx_index: 0, diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index 8cb152262a..fb4449e642 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -56,7 +56,7 @@ use xcm::prelude::{ }; use snowbridge_core::{ - inbound::{Log, Message, VerificationError, Verifier}, + inbound::{Message, VerificationError, Verifier}, sibling_sovereign_account, BasicOperatingMode, ParaId, }; use snowbridge_router_primitives::{ @@ -212,12 +212,12 @@ pub mod pallet { ensure!(!Self::operating_mode().is_halted(), Error::::Halted); // submit message to verifier for verification - T::Verifier::verify(&message.data, &message.proof) + T::Verifier::verify(&message.event_log, &message.proof) .map_err(|e| Error::::Verification(e))?; // Decode event log into an Envelope let envelope = - Envelope::try_from(message.data).map_err(|_| Error::::InvalidEnvelope)?; + Envelope::try_from(message.event_log).map_err(|_| Error::::InvalidEnvelope)?; // Verify that the message was submitted from the known Gateway contract ensure!(T::GatewayAddress::get() == envelope.gateway, Error::::InvalidGateway,); diff --git a/parachain/pallets/inbound-queue/src/test.rs b/parachain/pallets/inbound-queue/src/test.rs index e7b3224b65..90b5032161 100644 --- a/parachain/pallets/inbound-queue/src/test.rs +++ b/parachain/pallets/inbound-queue/src/test.rs @@ -10,7 +10,7 @@ use frame_support::{ use hex_literal::hex; use snowbridge_beacon_primitives::{Fork, ForkVersions}; use snowbridge_core::{ - inbound::{Message, Proof, VerificationError}, + inbound::{Log, Proof, VerificationError}, ParaId, }; use snowbridge_router_primitives::inbound::MessageToXcm; @@ -120,7 +120,7 @@ impl snowbridge_ethereum_beacon_client::Config for Test { pub struct MockVerifier; impl Verifier for MockVerifier { - fn verify(_: &Message) -> Result<(), VerificationError> { + fn verify(_: &Log, _: &Proof) -> Result<(), VerificationError> { Ok(()) } } @@ -219,26 +219,57 @@ pub fn new_tester() -> sp_io::TestExternalities { ext } -// dest para is 1000 -const OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( - " - f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 - " -); +// Generated from smoketests: +// cd smoketests +// ./make-bindings +// cargo test --test register_token -- --nocapture +fn mock_event_log() -> Log { + Log { + // gateway address + address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), + topics: vec![ + hex!("5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169").into(), + // destination parachain id + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + // message id + hex!("afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640f").into(), + ], + // Nonce + Payload + data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").into(), + } +} -// dest para is 1001 -const OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST: [u8; 254] = hex!( - " - f8fc94eda338e4dc46038493b885327842fd3e301cab39f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e9a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 - " -); +fn mock_event_log_invalid_dest() -> Log { + Log { + // gateway address + address: hex!("eda338e4dc46038493b885327842fd3e301cab39").into(), + topics: vec![ + hex!("5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169").into(), + // destination parachain id + hex!("00000000000000000000000000000000000000000000000000000000000003e9").into(), + // message id + hex!("afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640f").into(), + ], + // Nonce + Payload + data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").into(), + } +} -// gateway in message does not match configured gateway in runtimeå -const BAD_OUTBOUND_QUEUE_EVENT_LOG: [u8; 254] = hex!( - " - f8fc940000000000000000000000000000000000000000f863a05066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169a000000000000000000000000000000000000000000000000000000000000003e8a0afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640fb88000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000 - " -); +fn mock_event_log_invalid_gateway() -> Log { + Log { + // gateway address + address: H160::zero(), + topics: vec![ + hex!("5066fbba677e15936860e04088ca4cad3acd4c19706962196a5346f1457f7169").into(), + // destination parachain id + hex!("00000000000000000000000000000000000000000000000000000000000003e8").into(), + // message id + hex!("afad3c9777134532ae230b4fad334eef2e0dacbb965920412a7eaa59b07d640f").into(), + ], + // Nonce + Payload + data: hex!("00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001e000f000000000000000087d1f7fdfee7f651fabc8bfcb6e086c278b77a7d0000").into(), + } +} const XCM_HASH: [u8; 32] = [ 201, 101, 244, 67, 153, 61, 253, 203, 92, 23, 197, 172, 112, 209, 53, 248, 118, 25, 253, 110, @@ -260,7 +291,7 @@ fn test_submit_happy_path() { // Submit message let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), + event_log: mock_event_log(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), @@ -271,6 +302,8 @@ fn test_submit_happy_path() { expect_events(vec![InboundQueueEvent::MessageReceived { dest: ASSET_HUB_PARAID.into(), nonce: 1, + // The production runtime configuration will actually bubble up the embedded SetTopic as + // the messageID. So this XCM_HASH is only for unit tests. message_id: XCM_HASH, } .into()]); @@ -290,7 +323,7 @@ fn test_submit_xcm_send_failure() { // Submit message let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG_INVALID_DEST.into(), + event_log: mock_event_log_invalid_dest(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), @@ -316,7 +349,7 @@ fn test_submit_with_invalid_gateway() { // Submit message let message = Message { - data: BAD_OUTBOUND_QUEUE_EVENT_LOG.into(), + event_log: mock_event_log_invalid_gateway(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), @@ -342,7 +375,7 @@ fn test_submit_with_invalid_nonce() { // Submit message let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), + event_log: mock_event_log(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), @@ -374,7 +407,7 @@ fn test_submit_no_funds_to_reward_relayers() { // Submit message let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), + event_log: mock_event_log(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), @@ -394,7 +427,7 @@ fn test_set_operating_mode() { let relayer: AccountId = Keyring::Bob.into(); let origin = RuntimeOrigin::signed(relayer); let message = Message { - data: OUTBOUND_QUEUE_EVENT_LOG.into(), + event_log: mock_event_log(), proof: Proof { block_hash: Default::default(), tx_index: Default::default(), diff --git a/parachain/primitives/core/src/inbound.rs b/parachain/primitives/core/src/inbound.rs index a32689e26a..4b04470ad0 100644 --- a/parachain/primitives/core/src/inbound.rs +++ b/parachain/primitives/core/src/inbound.rs @@ -19,9 +19,9 @@ pub trait Verifier { pub enum VerificationError { /// Execution header is missing HeaderNotFound, - /// Log was not found in the verified transaction receipt + /// Event log was not found in the verified transaction receipt LogNotFound, - /// Data payload does not decode into a valid Log + /// Event log has an invalid format InvalidLog, /// Unable to verify the transaction receipt with the provided proof InvalidProof, @@ -32,21 +32,36 @@ pub type MessageNonce = u64; /// A bridge message from the Gateway contract on Ethereum #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Message { - /// Event log - pub data: Log, + /// Event log emitted by Gateway contract + pub event_log: Log, /// Inclusion proof for a transaction receipt containing the event log pub proof: Proof, } +const MAX_TOPICS: usize = 4; + +#[derive(Clone, RuntimeDebug)] +pub enum LogValidationError { + TooManyTopics, +} + /// Event log -#[derive(Clone, Encode, Decode, RuntimeDebug, TypeInfo)] -#[cfg_attr(feature = "std", derive(PartialEq))] +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Log { pub address: H160, pub topics: Vec, pub data: Vec, } +impl Log { + pub fn validate(&self) -> Result<(), LogValidationError> { + if self.topics.len() > MAX_TOPICS { + return Err(LogValidationError::TooManyTopics) + } + Ok(()) + } +} + /// Inclusion proof for a transaction receipt #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] pub struct Proof { diff --git a/polkadot-sdk b/polkadot-sdk index f7fbba7532..61cbf8297c 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit f7fbba753247de67d36af870b2c69b8f2efc629a +Subproject commit 61cbf8297c35deeb6a515cffcca6b0af98f1c42b diff --git a/relayer/chain/ethereum/message.go b/relayer/chain/ethereum/message.go index 9659ec1867..901aeb3c29 100644 --- a/relayer/chain/ethereum/message.go +++ b/relayer/chain/ethereum/message.go @@ -5,7 +5,6 @@ package ethereum import ( "bytes" - "encoding/hex" etypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" @@ -36,8 +35,17 @@ func MakeMessageFromEvent(event *etypes.Log, receiptsTrie *etrie.Trie) (*paracha return nil, err } + var convertedTopics []types.H256 + for _, topic := range event.Topics { + convertedTopics = append(convertedTopics, types.H256(topic)) + } + m := parachain.Message{ - Data: buf.Bytes(), + EventLog: parachain.EventLog{ + Address: types.H160(event.Address), + Topics: convertedTopics, + Data: event.Data, + }, Proof: parachain.Proof{ BlockHash: types.NewH256(event.BlockHash.Bytes()), TxIndex: types.NewU32(uint32(event.TxIndex)), @@ -45,12 +53,10 @@ func MakeMessageFromEvent(event *etypes.Log, receiptsTrie *etrie.Trie) (*paracha }, } - value := hex.EncodeToString(m.Data) log.WithFields(logrus.Fields{ - "payload": value, - "blockHash": m.Proof.BlockHash.Hex(), - "eventIndex": m.Proof.TxIndex, - "txHash": event.TxHash.Hex(), + "EventLog": m.EventLog, + "Proof": m.Proof, + "txHash": event.TxHash.Hex(), }).Debug("Generated message from Ethereum log") return &m, nil diff --git a/relayer/chain/parachain/message.go b/relayer/chain/parachain/message.go index 9a60275f01..85bf8928ed 100644 --- a/relayer/chain/parachain/message.go +++ b/relayer/chain/parachain/message.go @@ -10,9 +10,15 @@ import ( "github.com/snowfork/go-substrate-rpc-client/v4/types" ) +type EventLog struct { + Address types.H160 + Topics []types.H256 + Data types.Bytes +} + type Message struct { - Data []byte - Proof Proof + EventLog EventLog + Proof Proof } type Proof struct { diff --git a/relayer/contracts/gateway.go b/relayer/contracts/gateway.go index 3a1979a228..56f2ae93f0 100644 --- a/relayer/contracts/gateway.go +++ b/relayer/contracts/gateway.go @@ -85,7 +85,7 @@ type VerificationProof struct { // GatewayMetaData contains all meta data concerning the Gateway contract. var GatewayMetaData = &bind.MetaData{ - ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"topicID\",\"type\":\"bytes32\"}],\"name\":\"Topic\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + ABI: "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"agent\",\"type\":\"address\"}],\"name\":\"AgentCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"AgentFundsWithdrawn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"ChannelUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"InboundMessageDispatched\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"enumOperatingMode\",\"name\":\"mode\",\"type\":\"uint8\"}],\"name\":\"OperatingModeChanged\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"ParaID\",\"name\":\"destination\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"messageID\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"payload\",\"type\":\"bytes\"}],\"name\":\"OutboundMessageAccepted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"TokenRegistrationSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"destinationAddress\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"TokenSent\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"implementation\",\"type\":\"address\"}],\"name\":\"Upgraded\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"agentID\",\"type\":\"bytes32\"}],\"name\":\"agentOf\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelFeeOf\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelNoncesOf\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"ParaID\",\"name\":\"paraID\",\"type\":\"uint256\"}],\"name\":\"channelOperatingModeOf\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"implementation\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"operatingMode\",\"outputs\":[{\"internalType\":\"enumOperatingMode\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"}],\"name\":\"registerToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"destinationAddress\",\"type\":\"bytes32\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"token\",\"type\":\"address\"},{\"internalType\":\"ParaID\",\"name\":\"destinationChain\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"destinationAddress\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"sendToken\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"ParaID\",\"name\":\"origin\",\"type\":\"uint256\"},{\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"internalType\":\"enumCommand\",\"name\":\"command\",\"type\":\"uint8\"},{\"internalType\":\"bytes\",\"name\":\"params\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"maxDispatchGas\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxRefund\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"reward\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"id\",\"type\":\"bytes32\"}],\"internalType\":\"structInboundMessage\",\"name\":\"message\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"components\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"number\",\"type\":\"uint256\"},{\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"bytes32\",\"name\":\"extrinsicsRoot\",\"type\":\"bytes32\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"kind\",\"type\":\"uint256\"},{\"internalType\":\"bytes4\",\"name\":\"consensusEngineID\",\"type\":\"bytes4\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"internalType\":\"structVerification.DigestItem[]\",\"name\":\"digestItems\",\"type\":\"tuple[]\"}],\"internalType\":\"structVerification.ParachainHeader\",\"name\":\"header\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint256\",\"name\":\"pos\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"width\",\"type\":\"uint256\"},{\"internalType\":\"bytes32[]\",\"name\":\"proof\",\"type\":\"bytes32[]\"}],\"internalType\":\"structVerification.HeadProof\",\"name\":\"headProof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"},{\"internalType\":\"uint32\",\"name\":\"parentNumber\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"parentHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"nextAuthoritySetID\",\"type\":\"uint64\"},{\"internalType\":\"uint32\",\"name\":\"nextAuthoritySetLen\",\"type\":\"uint32\"},{\"internalType\":\"bytes32\",\"name\":\"nextAuthoritySetRoot\",\"type\":\"bytes32\"}],\"internalType\":\"structVerification.MMRLeafPartial\",\"name\":\"leafPartial\",\"type\":\"tuple\"},{\"internalType\":\"bytes32[]\",\"name\":\"leafProof\",\"type\":\"bytes32[]\"},{\"internalType\":\"uint256\",\"name\":\"leafProofOrder\",\"type\":\"uint256\"}],\"internalType\":\"structVerification.Proof\",\"name\":\"headerProof\",\"type\":\"tuple\"}],\"name\":\"submitInbound\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", } // GatewayABI is the input ABI used to generate the binding from. @@ -1820,140 +1820,6 @@ func (_Gateway *GatewayFilterer) ParseTokenSent(log types.Log) (*GatewayTokenSen return event, nil } -// GatewayTopicIterator is returned from FilterTopic and is used to iterate over the raw logs and unpacked data for Topic events raised by the Gateway contract. -type GatewayTopicIterator struct { - Event *GatewayTopic // 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 *GatewayTopicIterator) 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(GatewayTopic) - 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(GatewayTopic) - 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 *GatewayTopicIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *GatewayTopicIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// GatewayTopic represents a Topic event raised by the Gateway contract. -type GatewayTopic struct { - TopicID [32]byte - Raw types.Log // Blockchain specific contextual infos -} - -// FilterTopic is a free log retrieval operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. -// -// Solidity: event Topic(bytes32 topicID) -func (_Gateway *GatewayFilterer) FilterTopic(opts *bind.FilterOpts) (*GatewayTopicIterator, error) { - - logs, sub, err := _Gateway.contract.FilterLogs(opts, "Topic") - if err != nil { - return nil, err - } - return &GatewayTopicIterator{contract: _Gateway.contract, event: "Topic", logs: logs, sub: sub}, nil -} - -// WatchTopic is a free log subscription operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. -// -// Solidity: event Topic(bytes32 topicID) -func (_Gateway *GatewayFilterer) WatchTopic(opts *bind.WatchOpts, sink chan<- *GatewayTopic) (event.Subscription, error) { - - logs, sub, err := _Gateway.contract.WatchLogs(opts, "Topic") - 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(GatewayTopic) - if err := _Gateway.contract.UnpackLog(event, "Topic", 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 -} - -// ParseTopic is a log parse operation binding the contract event 0xff076dd0e7b4feaccc2daf62ded04e4a813b1cd467b86b1a03eb8b0e5cb8763a. -// -// Solidity: event Topic(bytes32 topicID) -func (_Gateway *GatewayFilterer) ParseTopic(log types.Log) (*GatewayTopic, error) { - event := new(GatewayTopic) - if err := _Gateway.contract.UnpackLog(event, "Topic", 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/go.mod b/relayer/go.mod index 7796b8598f..450325b2b1 100644 --- a/relayer/go.mod +++ b/relayer/go.mod @@ -9,7 +9,7 @@ require ( github.com/magefile/mage v1.13.0 github.com/sirupsen/logrus v1.8.1 github.com/snowfork/ethashproof v0.0.0-20210729080250-93b61cd82454 - github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20230831112246-2cf362679c74 + github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20231109131025-3ece5b994f03 github.com/spf13/cobra v1.4.0 github.com/spf13/viper v1.12.0 github.com/stretchr/testify v1.8.1 diff --git a/relayer/go.sum b/relayer/go.sum index 3efed1ccce..e7ef284dfd 100644 --- a/relayer/go.sum +++ b/relayer/go.sum @@ -28,6 +28,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= @@ -84,6 +85,7 @@ github.com/aristanetworks/glog v0.0.0-20191112221043-67e8567f59f3/go.mod h1:KASm github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20200609010056-95bcf8053598/go.mod h1:QZe5Yh80Hp1b6JxQdpfSEEe8X7hTyTEZSosSrFf/oJE= github.com/aristanetworks/splunk-hec-go v0.3.3/go.mod h1:1VHO9r17b0K7WmOlLb9nTk/2YanvOEnLMUgsFrxBROc= +github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/aws/aws-sdk-go v1.25.48/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= @@ -140,6 +142,8 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cosmos/go-bip39 v0.0.0-20180819234021-555e2067c45d/go.mod h1:tSxLoYXyBmiFeKpvmq4dzayMdCjCnu8uqmCysIGBT2Y= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= @@ -162,10 +166,12 @@ github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMaSuZ+SZcx/wljOQKvp5srsbCiKDEb6K2wC4+PiBmQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= +github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/dop251/goja v0.0.0-20200219165308-d1232e640a87/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= @@ -191,6 +197,7 @@ github.com/ethereum/go-ethereum v1.10.26 h1:i/7d9RBBwiXCEuyduBQzJw/mKmnvzsN14jqB github.com/ethereum/go-ethereum v1.10.26/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= @@ -225,6 +232,7 @@ github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNI github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= +github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= @@ -233,6 +241,7 @@ github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg78 github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= @@ -240,6 +249,7 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfU github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= @@ -321,6 +331,10 @@ github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/b github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc= github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -345,9 +359,11 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/influxdata/flux v0.65.1/go.mod h1:J754/zds0vvpfwuq7Gc2wRdVwEodfpCFM7mYlOw2LqY= github.com/influxdata/influxdb v1.2.3-0.20180221223340-01288bdb0883/go.mod h1:qZna6X/4elxqT3yI9iZYdZrWWdeFOOprn86kgg4+IzY= github.com/influxdata/influxdb v1.8.3/go.mod h1:JugdFhsvvI8gadxOI6noqNeeBHvWNTbfYGtiAn+2jhI= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/influxdata/influxql v1.1.1-0.20200828144457-65d3ef77d385/go.mod h1:gHp9y86a/pxhjJ+zMjNXiQAA197Xk9wLxaz+fGG+kWk= github.com/influxdata/line-protocol v0.0.0-20180522152040-32c6aa80de5e/go.mod h1:4kt73NQhadE3daL3WhR5EJ/J2ocX0PZzwxQ0gXJ7oFE= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19ybifQhZoQNF5D8= github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= @@ -364,6 +380,7 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= @@ -396,6 +413,7 @@ github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= @@ -406,11 +424,13 @@ github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPK github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= @@ -424,13 +444,16 @@ github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b h1:QrHweqAtyJ9EwCaG github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b/go.mod h1:xxLb2ip6sSUts3g1irPVHyk/DGslwQsNOo9I7smJfNU= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= @@ -554,6 +577,8 @@ github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20230324140453-5bb90e7b1 github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20230324140453-5bb90e7b12b7/go.mod h1:MVk5+w9icYU7MViYFm7CKYhx1VMj6DpN2tWO6s4OK5g= github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20230831112246-2cf362679c74 h1:rUdiDH2OfZuqMQPVLP0v/tCrCZjAZNcibC9ceWJyFAY= github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20230831112246-2cf362679c74/go.mod h1:MVk5+w9icYU7MViYFm7CKYhx1VMj6DpN2tWO6s4OK5g= +github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20231109131025-3ece5b994f03 h1:MdYbdpjFGIV3znyTYGsQd2ea/rNme9iQFwW85iX/YmY= +github.com/snowfork/go-substrate-rpc-client/v4 v4.0.1-0.20231109131025-3ece5b994f03/go.mod h1:MVk5+w9icYU7MViYFm7CKYhx1VMj6DpN2tWO6s4OK5g= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.0.1-0.20190317074736-539464a789e9/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= @@ -639,9 +664,13 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -852,6 +881,7 @@ golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1016,6 +1046,7 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= diff --git a/smoketest/tests/register_token.rs b/smoketest/tests/register_token.rs index d8d4af6469..47738c65f5 100644 --- a/smoketest/tests/register_token.rs +++ b/smoketest/tests/register_token.rs @@ -1,7 +1,7 @@ use codec::Encode; use ethers::{ - core::types::Address, - utils::{parse_units, rlp::Encodable}, + core::types::{Address, Log}, + utils::{parse_units}, }; use futures::StreamExt; use snowbridge_smoketest::{ @@ -52,8 +52,9 @@ async fn register_token() { // Log for OutboundMessageAccepted let outbound_message_accepted_log = receipt.logs.last().unwrap(); - // RLP-encode log and print it - println!("receipt log: {:#?}", hex::encode(outbound_message_accepted_log.rlp_bytes())); + + // print log for unit tests + print_event_log_for_unit_tests(outbound_message_accepted_log); assert_eq!(receipt.status.unwrap().as_u64(), 1u64); @@ -94,3 +95,17 @@ async fn register_token() { } assert!(created_event_found) } + +fn print_event_log_for_unit_tests(log: &Log) { + let topics: Vec = log.topics.iter().map(|t| hex::encode(t.as_ref())).collect(); + println!("Log {{"); + println!(" address: hex!(\"{}\").into(),", hex::encode(log.address.as_ref())); + println!(" topics: vec!["); + for topic in topics.iter() { + println!(" hex!(\"{}\").into(),", topic); + } + println!(" ],"); + println!(" data: hex!(\"{}\").into(),", hex::encode(&log.data)); + + println!("}}") +} From cf4a83fa3d5319d67a131c0878e1b81b5412b6d9 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 16:34:09 +0200 Subject: [PATCH 15/20] Remove obsolete errors from ethereum-beacon-client --- parachain/pallets/ethereum-beacon-client/src/lib.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/parachain/pallets/ethereum-beacon-client/src/lib.rs b/parachain/pallets/ethereum-beacon-client/src/lib.rs index 9c0d435624..0f3cf025b5 100644 --- a/parachain/pallets/ethereum-beacon-client/src/lib.rs +++ b/parachain/pallets/ethereum-beacon-client/src/lib.rs @@ -134,9 +134,6 @@ pub mod pallet { InvalidAncestryMerkleProof, InvalidBlockRootsRootMerkleProof, HeaderNotFinalized, - MissingHeader, - InvalidProof, - DecodeFailed, BlockBodyHashTreeRootFailed, HeaderHashTreeRootFailed, SyncCommitteeHashTreeRootFailed, From b18bc2a5edaf56b33cfe0b876a49eb2b0c8b03a6 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 16:59:32 +0200 Subject: [PATCH 16/20] fix clippy warning --- parachain/pallets/inbound-queue/src/envelope.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/parachain/pallets/inbound-queue/src/envelope.rs b/parachain/pallets/inbound-queue/src/envelope.rs index 0e2b0f8753..86c3d7f79e 100644 --- a/parachain/pallets/inbound-queue/src/envelope.rs +++ b/parachain/pallets/inbound-queue/src/envelope.rs @@ -40,7 +40,7 @@ impl TryFrom for Envelope { .map_err(|_| EnvelopeDecodeError)?; Ok(Self { - gateway: H160::from(log.address), + gateway: log.address, dest: event.destination.saturating_to::().into(), nonce: event.nonce, message_id: H256::from(event.messageID.as_ref()), From 61f1f1da00a5f8cfa15104cdd8a13ae272af7ac5 Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 17:25:27 +0200 Subject: [PATCH 17/20] update polkadot-sdk --- polkadot-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot-sdk b/polkadot-sdk index 224c8597ad..8b740081ae 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit 224c8597ad06da96ad9183adb38c145f4626f409 +Subproject commit 8b740081ae803c932296ba86b7979307fd12a49a From 85dc7cdcfaafc7437d6d9ef11cd6b66f07c3643d Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Thu, 9 Nov 2023 18:23:33 +0200 Subject: [PATCH 18/20] fix clippy --- parachain/pallets/inbound-queue/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/parachain/pallets/inbound-queue/src/lib.rs b/parachain/pallets/inbound-queue/src/lib.rs index 2de4715c42..fb4449e642 100644 --- a/parachain/pallets/inbound-queue/src/lib.rs +++ b/parachain/pallets/inbound-queue/src/lib.rs @@ -36,7 +36,6 @@ pub mod weights; #[cfg(test)] mod test; -use alloy_rlp::Decodable as RlpDecodable; use codec::{Decode, DecodeAll, Encode}; use envelope::Envelope; use frame_support::{ From bda3f7aded27a8ecc03a46ccf6ab46097167f45a Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Fri, 10 Nov 2023 20:13:39 +0200 Subject: [PATCH 19/20] unnecessary typeinfo --- parachain/primitives/ethereum/src/log.rs | 3 +-- parachain/primitives/ethereum/src/receipt.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/parachain/primitives/ethereum/src/log.rs b/parachain/primitives/ethereum/src/log.rs index 021ab16776..7b8e35bb11 100644 --- a/parachain/primitives/ethereum/src/log.rs +++ b/parachain/primitives/ethereum/src/log.rs @@ -2,10 +2,9 @@ // SPDX-FileCopyrightText: 2023 Snowfork use codec::{Decode, Encode}; use ethereum_types::{H160, H256}; -use scale_info::TypeInfo; use sp_std::prelude::*; -#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, Default, TypeInfo)] +#[derive(Clone, Debug, Encode, Decode, PartialEq, Eq)] pub struct Log { pub address: H160, pub topics: Vec, diff --git a/parachain/primitives/ethereum/src/receipt.rs b/parachain/primitives/ethereum/src/receipt.rs index c2efa3ae61..665a93dbb1 100644 --- a/parachain/primitives/ethereum/src/receipt.rs +++ b/parachain/primitives/ethereum/src/receipt.rs @@ -2,11 +2,10 @@ // SPDX-FileCopyrightText: 2023 Snowfork use crate::{Bloom, Log}; use codec::{Decode, Encode}; -use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; use sp_std::prelude::*; -#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo)] +#[derive(Clone, Default, Encode, Decode, PartialEq, RuntimeDebug)] pub struct Receipt { pub post_state_or_status: Vec, pub cumulative_gas_used: u64, From e23ac895f609dc8cb8cfb3dd385c30c64e08299a Mon Sep 17 00:00:00 2001 From: Vincent Geddes Date: Sun, 12 Nov 2023 16:12:44 +0200 Subject: [PATCH 20/20] update polkadot-sdk --- polkadot-sdk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/polkadot-sdk b/polkadot-sdk index 483488f37a..5fec1d3eeb 160000 --- a/polkadot-sdk +++ b/polkadot-sdk @@ -1 +1 @@ -Subproject commit 483488f37a9b80a8f5e8c203286116010251429c +Subproject commit 5fec1d3eebe5bbae911a3be9b6e653acd65ae5a9