Skip to content
This repository has been archived by the owner on Oct 22, 2024. It is now read-only.

Ignore reward when funds unavailable #118

Merged
merged 7 commits into from
Feb 28, 2024
Merged
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
13 changes: 13 additions & 0 deletions bridges/snowbridge/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,16 @@ derivable_impls = { level = "allow", priority = 2 } # false pos
stable_sort_primitive = { level = "allow", priority = 2 } # prefer stable sort
extra-unused-type-parameters = { level = "allow", priority = 2 } # stylistic
default_constructed_unit_structs = { level = "allow", priority = 2 } # stylistic

[workspace.dependencies]
polkavm-linker = "0.8.2"
polkavm-derive = "0.8.0"
log = { version = "0.4.20", default-features = false }
quote = { version = "1.0.33" }
serde = { version = "1.0.197", default-features = false }
serde-big-array = { version = "0.3.2" }
serde_derive = { version = "1.0.117" }
serde_json = { version = "1.0.114", default-features = false }
serde_yaml = { version = "0.9" }
syn = { version = "2.0.50" }
thiserror = { version = "1.0.48" }
17 changes: 13 additions & 4 deletions bridges/snowbridge/pallets/inbound-queue/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,15 @@ use envelope::Envelope;
use frame_support::{
traits::{
fungible::{Inspect, Mutate},
tokens::Preservation,
tokens::{Fortitude, Preservation},
},
weights::WeightToFee,
PalletError,
};
use frame_system::ensure_signed;
use scale_info::TypeInfo;
use sp_core::{H160, H256};
use sp_runtime::traits::Zero;
use sp_std::{convert::TryFrom, vec};
use xcm::prelude::{
send_xcm, Instruction::SetTopic, Junction::*, Location, SendError as XcmpSendError, SendXcm,
Expand Down Expand Up @@ -261,11 +262,19 @@ pub mod pallet {
}
})?;

// Reward relayer from the sovereign account of the destination parachain
// Expected to fail if sovereign account has no funds
// 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(message.encode().len() as u32);
T::Token::transfer(&sovereign_account, &who, delivery_cost, Preservation::Preserve)?;
let amount = T::Token::reducible_balance(
&sovereign_account,
Preservation::Preserve,
Fortitude::Polite,
)
.min(delivery_cost);
if amount > BalanceOf::<T>::zero() {
T::Token::transfer(&sovereign_account, &who, amount, Preservation::Preserve)?;
}

// Decode message into XCM
let (xcm, fee) =
Expand Down
8 changes: 6 additions & 2 deletions bridges/snowbridge/pallets/inbound-queue/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use super::*;

use frame_support::{
parameter_types,
traits::{ConstU128, ConstU32, Everything},
traits::{ConstU32, Everything},
weights::IdentityFee,
};
use hex_literal::hex;
Expand Down Expand Up @@ -74,14 +74,18 @@ impl frame_system::Config for Test {
type Block = Block;
}

parameter_types! {
pub const ExistentialDeposit: u128 = 1;
}

impl pallet_balances::Config for Test {
type MaxLocks = ();
type MaxReserves = ();
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type RuntimeEvent = RuntimeEvent;
type DustRemoval = ();
type ExistentialDeposit = ConstU128<1>;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = System;
type WeightInfo = ();
type FreezeIdentifier = ();
Expand Down
55 changes: 48 additions & 7 deletions bridges/snowbridge/pallets/inbound-queue/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use frame_support::{assert_noop, assert_ok};
use hex_literal::hex;
use snowbridge_core::{inbound::Proof, ChannelId};
use sp_keyring::AccountKeyring as Keyring;
use sp_runtime::{DispatchError, TokenError};
use sp_runtime::DispatchError;
use sp_std::convert::From;

use crate::{Error, Event as InboundQueueEvent};
Expand Down Expand Up @@ -150,12 +150,12 @@ fn test_submit_with_invalid_nonce() {
}

#[test]
fn test_submit_no_funds_to_reward_relayers() {
fn test_submit_no_funds_to_reward_relayers_just_ignore() {
new_tester().execute_with(|| {
let relayer: AccountId = Keyring::Bob.into();
let origin = RuntimeOrigin::signed(relayer);

// Reset balance of sovereign_account to zero so to trigger the FundsUnavailable error
// Reset balance of sovereign_account to zero first
let sovereign_account = sibling_sovereign_account::<Test>(ASSET_HUB_PARAID.into());
Balances::set_balance(&sovereign_account, 0);

Expand All @@ -168,10 +168,8 @@ fn test_submit_no_funds_to_reward_relayers() {
data: Default::default(),
},
};
assert_noop!(
InboundQueue::submit(origin.clone(), message.clone()),
TokenError::FundsUnavailable
);
// Check submit successfully in case no funds available
assert_ok!(InboundQueue::submit(origin.clone(), message.clone()));
});
}

Expand Down Expand Up @@ -210,3 +208,46 @@ fn test_set_operating_mode_root_only() {
);
});
}

#[test]
fn test_submit_no_funds_to_reward_relayers_and_ed_preserved() {
new_tester().execute_with(|| {
let relayer: AccountId = Keyring::Bob.into();
let origin = RuntimeOrigin::signed(relayer);

// Reset balance of sovereign account to (ED+1) first
let sovereign_account = sibling_sovereign_account::<Test>(ASSET_HUB_PARAID.into());
Balances::set_balance(&sovereign_account, ExistentialDeposit::get() + 1);

// Submit message successfully
let message = Message {
event_log: mock_event_log(),
proof: Proof {
block_hash: Default::default(),
tx_index: Default::default(),
data: Default::default(),
},
};
assert_ok!(InboundQueue::submit(origin.clone(), message.clone()));

// Check balance of sovereign account to ED
let amount = Balances::balance(&sovereign_account);
assert_eq!(amount, ExistentialDeposit::get());

// Submit another message with nonce set as 2
let mut event_log = mock_event_log();
event_log.data[31] = 2;
let message = Message {
event_log,
proof: Proof {
block_hash: Default::default(),
tx_index: Default::default(),
data: Default::default(),
},
};
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());
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use snowbridge_pallet_inbound_queue_fixtures::{
use snowbridge_pallet_system;
use snowbridge_router_primitives::inbound::GlobalConsensusEthereumConvertsFor;
use sp_core::H256;
use sp_runtime::{ArithmeticError::Underflow, DispatchError::Arithmetic};
use sp_runtime::{DispatchError::Token, TokenError::FundsUnavailable};
use testnet_parachains_constants::rococo::snowbridge::EthereumNetwork;

const INITIAL_FUND: u128 = 5_000_000_000 * ROCOCO_ED;
Expand Down Expand Up @@ -532,6 +532,6 @@ fn send_token_from_ethereum_to_asset_hub_fail_for_insufficient_fund() {
BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id().into(), 1_000);

BridgeHubRococo::execute_with(|| {
assert_err!(send_inbound_message(make_register_token_message()), Arithmetic(Underflow));
assert_err!(send_inbound_message(make_register_token_message()), Token(FundsUnavailable));
});
}
Loading