Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
530 changes: 334 additions & 196 deletions Cargo.lock

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -626,6 +626,10 @@ Inflector = { version = "0.11.4" }
aes-gcm = { version = "0.10" }
ahash = { version = "0.8.2" }
alloy-core = { version = "1.1.0", default-features = false }
# TODO: remove alloy-primitives and alloy-sol-types, they are re-exported in alloy-core
# but the version is different so it doesnt compile
alloy-primitives = { version = "0.4.2", default-features = false }
alloy-sol-types = { version = "0.4.2", default-features = false }
always-assert = { version = "0.1" }
anyhow = { version = "1.0.81", default-features = false }
approx = { version = "0.5.1" }
Expand All @@ -643,7 +647,6 @@ ark-ed-on-bls12-377-ext = { version = "0.4.1", default-features = false }
ark-ed-on-bls12-381-bandersnatch = { version = "0.4.0", default-features = false }
ark-ed-on-bls12-381-bandersnatch-ext = { version = "0.4.1", default-features = false }
ark-scale = { version = "0.0.12", default-features = false }
ark-vrf = { version = "0.1.0", default-features = false }
array-bytes = { version = "6.2.2", default-features = false }
arrayvec = { version = "0.7.4" }
assert_cmd = { version = "2.0.14" }
Expand Down Expand Up @@ -671,7 +674,7 @@ blake2 = { version = "0.10.4", default-features = false }
blake2b_simd = { version = "1.0.2", default-features = false }
blake3 = { version = "1.5" }
bn = { package = "substrate-bn", version = "0.6", default-features = false }
bounded-collections = { version = "0.2.3", default-features = false }
bounded-collections = { version = "0.3.2", default-features = false }
bounded-vec = { version = "0.7" }
bp-asset-hub-rococo = { path = "cumulus/parachains/runtimes/assets/asset-hub-rococo/bridge-primitives", default-features = false }
bp-asset-hub-westend = { path = "cumulus/parachains/runtimes/assets/asset-hub-westend/bridge-primitives", default-features = false }
Expand Down Expand Up @@ -1499,7 +1502,6 @@ overflow-checks = true
#
# This list is ordered alphabetically.
[profile.dev.package]
ark-vrf = { opt-level = 3 }
blake2 = { opt-level = 3 }
blake2b_simd = { opt-level = 3 }
chacha20poly1305 = { opt-level = 3 }
Expand Down
2 changes: 1 addition & 1 deletion bridges/snowbridge/pallets/ethereum-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub mod weights;
#[cfg(any(test, feature = "fuzzing"))]
pub mod mock;

#[cfg(test)]
#[cfg(any(test, feature = "fuzzing"))]
pub mod mock_electra;

#[cfg(test)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,7 @@ mod benchmarks {
fn submit() -> Result<(), BenchmarkError> {
let caller: T::AccountId = whitelisted_caller();

let create_message = make_register_token_message();

T::Helper::initialize_storage(
create_message.finalized_header,
create_message.block_roots_root,
);
let create_message = T::Helper::initialize_storage();

let sovereign_account = sibling_sovereign_account::<T>(1000u32.into());

Expand Down
105 changes: 54 additions & 51 deletions bridges/snowbridge/pallets/inbound-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
//! parachain.
#![cfg_attr(not(feature = "std"), no_std)]

mod envelope;

#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;

Expand All @@ -35,10 +33,11 @@ mod mock;

#[cfg(test)]
mod test;
pub mod xcm_message_processor;

use codec::{Decode, DecodeAll, Encode};
use envelope::Envelope;
use codec::{Decode, Encode};
use frame_support::{
pallet_prelude::DispatchResult,
traits::{
fungible::{Inspect, Mutate},
tokens::{Fortitude, Preservation},
Expand All @@ -48,7 +47,7 @@ use frame_support::{
};
use frame_system::ensure_signed;
use scale_info::TypeInfo;
use sp_core::H160;
use sp_core::{H160, H256};
use sp_runtime::traits::Zero;
use sp_std::vec;
use xcm::prelude::{
Expand All @@ -61,16 +60,20 @@ use snowbridge_core::{
StaticLookup,
};
use snowbridge_inbound_queue_primitives::{
v1::{ConvertMessage, ConvertMessageError, VersionedMessage},
v1::{ConvertMessage, ConvertMessageError, VersionedXcmMessage},
EventProof, VerificationError, Verifier,
};

use sp_runtime::{traits::Saturating, SaturatedConversion, TokenError};

use snowbridge_inbound_queue_primitives::v1::{Envelope, MessageProcessor};

pub use weights::WeightInfo;

#[cfg(feature = "runtime-benchmarks")]
use snowbridge_beacon_primitives::BeaconHeader;
#[cfg(feature = "runtime-benchmarks")]
use snowbridge_inbound_queue_primitives::EventFixture;

type BalanceOf<T> =
<<T as pallet::Config>::Token as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
Expand All @@ -79,20 +82,54 @@ pub use pallet::*;

pub const LOG_TARGET: &str = "snowbridge-inbound-queue";

pub trait RewardProcessor<T: frame_system::Config> {
fn process_reward(who: T::AccountId, channel: Channel, message: EventProof) -> DispatchResult;
}

impl<T: frame_system::Config> RewardProcessor<T> for () {
fn process_reward(
_who: T::AccountId,
_channel: Channel,
_message: EventProof,
) -> DispatchResult {
Ok(())
}
}

pub struct RewardThroughSovereign<T>(sp_std::marker::PhantomData<T>);

impl<T: pallet::Config> RewardProcessor<T> for RewardThroughSovereign<T> {
fn process_reward(who: T::AccountId, channel: Channel, event: EventProof) -> DispatchResult {
let length = event.encode().len() as u32;
let delivery_cost = pallet::Pallet::<T>::calculate_delivery_cost(length);
let sovereign_account: T::AccountId = sibling_sovereign_account::<T>(channel.para_id);

let amount = T::Token::reducible_balance(
&sovereign_account,
Preservation::Preserve,
Fortitude::Polite,
)
.min(delivery_cost);
if !amount.is_zero() {
T::Token::transfer(&sovereign_account, &who, amount, Preservation::Preserve)?;
}

Ok(())
}
}
#[frame_support::pallet]
pub mod pallet {
use super::*;

use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
use sp_core::H256;

#[pallet::pallet]
pub struct Pallet<T>(_);

#[cfg(feature = "runtime-benchmarks")]
pub trait BenchmarkHelper<T> {
fn initialize_storage(beacon_header: BeaconHeader, block_roots_root: H256);
fn initialize_storage() -> EventFixture;
}

#[pallet::config]
Expand Down Expand Up @@ -141,6 +178,12 @@ pub mod pallet {

/// To withdraw and deposit an asset.
type AssetTransactor: TransactAsset;

/// Process the message that was submitted
type MessageProcessor: MessageProcessor;

/// Process the reward to the relayer
type RewardProcessor: RewardProcessor<Self>;
}

#[pallet::hooks]
Expand Down Expand Up @@ -265,48 +308,8 @@ pub mod pallet {
}
})?;

// Reward relayer from the sovereign account of the destination parachain, only if funds
// are available
let sovereign_account = sibling_sovereign_account::<T>(channel.para_id);
let delivery_cost = Self::calculate_delivery_cost(event.encode().len() as u32);
let amount = T::Token::reducible_balance(
&sovereign_account,
Preservation::Preserve,
Fortitude::Polite,
)
.min(delivery_cost);
if !amount.is_zero() {
T::Token::transfer(&sovereign_account, &who, amount, Preservation::Preserve)?;
}

// Decode payload into `VersionedMessage`
let message = VersionedMessage::decode_all(&mut envelope.payload.as_ref())
.map_err(|_| Error::<T>::InvalidPayload)?;

// Decode message into XCM
let (xcm, fee) = Self::do_convert(envelope.message_id, message.clone())?;

log::info!(
target: LOG_TARGET,
"💫 xcm decoded as {:?} with fee {:?}",
xcm,
fee
);

// Burning fees for teleport
Self::burn_fees(channel.para_id, fee)?;

// Attempt to send XCM to a dest parachain
let message_id = Self::send_xcm(xcm, channel.para_id)?;

Self::deposit_event(Event::MessageReceived {
channel_id: envelope.channel_id,
nonce: envelope.nonce,
message_id,
fee_burned: fee,
});

Ok(())
T::RewardProcessor::process_reward(who, channel.clone(), event)?;
T::MessageProcessor::process_message(channel, envelope)
}

/// Halt or resume all pallet operations. May only be called by root.
Expand All @@ -326,7 +329,7 @@ pub mod pallet {
impl<T: Config> Pallet<T> {
pub fn do_convert(
message_id: H256,
message: VersionedMessage,
message: VersionedXcmMessage,
) -> Result<(Xcm<()>, BalanceOf<T>), Error<T>> {
let (xcm, fee) = T::MessageConverter::convert(message_id, message)
.map_err(|e| Error::<T>::ConvertMessage(e))?;
Expand Down
50 changes: 44 additions & 6 deletions bridges/snowbridge/pallets/inbound-queue/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,19 @@
// SPDX-FileCopyrightText: 2023 Snowfork <hello@snowfork.com>
use super::*;

use frame_support::{derive_impl, parameter_types, traits::ConstU32, weights::IdentityFee};
use crate::{
xcm_message_processor::XcmMessageProcessor,
{self as inbound_queue},
};
use frame_support::{
derive_impl, parameter_types,
storage::Key,
traits::{
tokens::{Fortitude, Preservation},
ConstU32,
},
weights::IdentityFee,
};
use hex_literal::hex;
use snowbridge_beacon_primitives::{
types::deneb, BeaconHeader, ExecutionProof, Fork, ForkVersions, VersionedExecutionPayloadHeader,
Expand All @@ -11,10 +23,11 @@ use snowbridge_core::{
gwei, meth, Channel, ChannelId, PricingParameters, Rewards, StaticLookup, TokenId,
};
use snowbridge_inbound_queue_primitives::{v1::MessageToXcm, Log, Proof, VerificationError};
use sp_core::{H160, H256};
use sp_core::{Get, H160, H256};
use sp_keyring::AccountKeyring as Keyring;
use sp_runtime::{
traits::{IdentifyAccount, IdentityLookup, MaybeConvert, Verify},
BuildStorage, FixedU128, MultiSignature,
traits::{IdentifyAccount, IdentityLookup, MaybeConvert, MaybeEquivalence, Verify, Zero},
BuildStorage, DispatchError, FixedU128, MultiSignature,
};
use sp_std::{convert::From, default::Default};
use xcm::{
Expand All @@ -23,8 +36,6 @@ use xcm::{
};
use xcm_executor::AssetsInHolding;

use crate::{self as inbound_queue};

type Block = frame_system::mocking::MockBlock<Test>;

frame_support::construct_runtime!(
Expand Down Expand Up @@ -220,6 +231,30 @@ impl MaybeConvert<TokenId, Location> for MockTokenIdConvert {
}
}

pub struct DummyPrefix;

impl MessageProcessor for DummyPrefix {
fn can_process_message(_channel: &Channel, _envelope: &Envelope) -> bool {
false
}

fn process_message(_channel: Channel, _envelope: Envelope) -> Result<(), DispatchError> {
panic!("DummyPrefix::process_message shouldn't be called");
}
}

pub struct DummySuffix;

impl MessageProcessor for DummySuffix {
fn can_process_message(_channel: &Channel, _envelope: &Envelope) -> bool {
true
}

fn process_message(_channel: Channel, _envelope: Envelope) -> Result<(), DispatchError> {
panic!("DummySuffix::process_message shouldn't be called");
}
}

impl inbound_queue::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Verifier = MockVerifier;
Expand All @@ -245,6 +280,9 @@ impl inbound_queue::Config for Test {
type LengthToFee = IdentityFee<u128>;
type MaxMessageSize = ConstU32<1024>;
type AssetTransactor = SuccessfulTransactor;
type MessageProcessor = (DummyPrefix, XcmMessageProcessor<Test>, DummySuffix); // We are passively testing if implementation of MessageProcessor trait works correctly for
// tuple
type RewardProcessor = RewardThroughSovereign<Self>;
}

pub fn setup() {
Expand Down
14 changes: 7 additions & 7 deletions bridges/snowbridge/pallets/inbound-queue/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ fn test_submit_happy_path() {

let origin = RuntimeOrigin::signed(relayer.clone());

// Submit event proof
let event = EventProof {
// Submit message
let message = Message {
event_log: mock_event_log(),
proof: Proof {
receipt_proof: Default::default(),
Expand Down Expand Up @@ -72,8 +72,8 @@ fn test_submit_xcm_invalid_channel() {
println!("account: {}", sovereign_account);
let _ = Balances::mint_into(&sovereign_account, 10000);

// Submit event proof
let event = EventProof {
// Submit message
let message = Message {
event_log: mock_event_log_invalid_channel(),
proof: Proof {
receipt_proof: Default::default(),
Expand All @@ -97,8 +97,8 @@ fn test_submit_with_invalid_gateway() {
let sovereign_account = sibling_sovereign_account::<Test>(ASSET_HUB_PARAID.into());
let _ = Balances::mint_into(&sovereign_account, 10000);

// Submit event proof
let event = EventProof {
// Submit message
let message = Message {
event_log: mock_event_log_invalid_gateway(),
proof: Proof {
receipt_proof: Default::default(),
Expand Down Expand Up @@ -237,7 +237,7 @@ fn test_submit_no_funds_to_reward_relayers_and_ed_preserved() {
execution_proof: mock_execution_proof(),
},
};
assert_ok!(InboundQueue::submit(origin.clone(), event.clone()));
assert_ok!(InboundQueue::submit(origin.clone(), message.clone()));
// Check balance of sovereign account as ED does not change
let amount = Balances::balance(&sovereign_account);
assert_eq!(amount, ExistentialDeposit::get());
Expand Down
Loading
Loading