Add Derived Account Origins to Dispatcher (#519)

* Update some docs

* Add derived account origin

* Add tests for derived origin

* Do a little bit of cleanup

* Change Origin type to use AccountIds instead of Public keys

* Update (most) tests to use new Origin types

* Remove redundant test

* Update `runtime-common` tests to use new Origin types

* Remove unused import

* Fix documentation around origin verification

* Update config types to use AccountIds in runtime

* Update Origin type used in message relay

* Use correct type when verifying message origin

* Make CallOrigin docs more consistent

* Use AccountIds instead of Public keys in Runtime types

* Introduce trait for converting AccountIds

* Bring back standalone function for deriving account IDs

* Remove AccountIdConverter configuration trait

* Remove old bridge_account_id derivation function

* Handle target ID decoding errors more gracefully

* Update message-lane to use new AccountId derivation

* Update merged code to use new Origin types

* Use explicit conversion between H256 and AccountIds

* Make relayer fund account a config option in `message-lane` pallet

* Add note about deriving the same account on different chains

* Fix test weight

* Use AccountId instead of Public key when signing Calls

* Semi-hardcode relayer fund address into Message Lane pallet
This commit is contained in:
Hernando Castano
2020-11-30 14:49:09 -05:00
committed by Bastian Köcher
parent c20b4c868f
commit 951aa36c2b
15 changed files with 383 additions and 203 deletions
@@ -18,8 +18,7 @@
//! All payments are instant.
use bp_message_lane::source_chain::MessageDeliveryAndDispatchPayment;
use bp_runtime::{bridge_account_id, MESSAGE_LANE_MODULE_PREFIX, NO_INSTANCE_ID};
use codec::Decode;
use codec::Encode;
use frame_support::traits::{Currency as CurrencyT, ExistenceRequirement};
use sp_std::fmt::Debug;
@@ -33,23 +32,26 @@ impl<AccountId, Currency> MessageDeliveryAndDispatchPayment<AccountId, Currency:
for InstantCurrencyPayments<AccountId, Currency>
where
Currency: CurrencyT<AccountId>,
AccountId: Debug + Default + Decode,
AccountId: Debug + Default + Encode,
{
type Error = &'static str;
fn pay_delivery_and_dispatch_fee(submitter: &AccountId, fee: &Currency::Balance) -> Result<(), Self::Error> {
Currency::transfer(
submitter,
&relayers_fund_account(),
*fee,
ExistenceRequirement::AllowDeath,
)
.map_err(Into::into)
fn pay_delivery_and_dispatch_fee(
submitter: &AccountId,
fee: &Currency::Balance,
relayer_fund_account: &AccountId,
) -> Result<(), Self::Error> {
Currency::transfer(submitter, relayer_fund_account, *fee, ExistenceRequirement::AllowDeath).map_err(Into::into)
}
fn pay_relayer_reward(_confirmation_relayer: &AccountId, relayer: &AccountId, reward: &Currency::Balance) {
fn pay_relayer_reward(
_confirmation_relayer: &AccountId,
relayer: &AccountId,
reward: &Currency::Balance,
relayer_fund_account: &AccountId,
) {
let pay_result = Currency::transfer(
&relayers_fund_account(),
&relayer_fund_account,
relayer,
*reward,
ExistenceRequirement::AllowDeath,
@@ -73,9 +75,3 @@ where
}
}
}
/// Return account id of shared relayers-fund account that is storing all fees
/// paid by submitters, until they're claimed by relayers.
fn relayers_fund_account<AccountId: Default + Decode>() -> AccountId {
bridge_account_id(NO_INSTANCE_ID, MESSAGE_LANE_MODULE_PREFIX)
}
+18
View File
@@ -95,6 +95,11 @@ pub trait Trait<I = DefaultInstance>: frame_system::Trait {
/// Identifier of relayer that deliver messages to this chain. Relayer reward is paid on the bridged chain.
type InboundRelayer: Parameter;
/// A type which can be turned into an AccountId from a 256-bit hash.
///
/// Used when deriving the shared relayer fund account.
type AccountIdConverter: sp_runtime::traits::Convert<sp_core::hash::H256, Self::AccountId>;
// Types that are used by outbound_lane (on source chain).
/// Target header chain.
@@ -267,6 +272,7 @@ decl_module! {
T::MessageDeliveryAndDispatchPayment::pay_delivery_and_dispatch_fee(
&submitter,
&delivery_and_dispatch_fee,
&relayer_fund_account_id::<T, I>(),
).map_err(|err| {
frame_support::debug::trace!(
"Message to lane {:?} is rejected because submitter {:?} is unable to pay fee {:?}: {:?}",
@@ -396,6 +402,7 @@ decl_module! {
let received_range = lane.confirm_delivery(lane_data.latest_received_nonce);
if let Some(received_range) = received_range {
Self::deposit_event(RawEvent::MessagesDelivered(lane_id, received_range.0, received_range.1));
let relayer_fund_account = relayer_fund_account_id::<T, I>();
// reward relayers that have delivered messages
// this loop is bounded by `T::MaxUnconfirmedMessagesAtInboundLane` on the bridged chain
@@ -413,6 +420,7 @@ decl_module! {
&confirmation_relayer,
&relayer,
&message_data.fee,
&relayer_fund_account,
);
}
}
@@ -636,6 +644,16 @@ fn verify_and_decode_messages_proof<Chain: SourceHeaderChain<Fee>, Fee, Dispatch
})
}
/// AccountId of the shared relayer fund account.
///
/// This account stores all the fees paid by submitters. Relayers are able to claim these
/// funds as at their convenience.
fn relayer_fund_account_id<T: Trait<I>, I: Instance>() -> T::AccountId {
use sp_runtime::traits::Convert;
let encoded_id = bp_runtime::derive_relayer_fund_account_id(bp_runtime::NO_INSTANCE_ID);
T::AccountIdConverter::convert(encoded_id)
}
#[cfg(test)]
mod tests {
use super::*;
+21 -2
View File
@@ -36,6 +36,14 @@ pub type TestPayload = (u64, Weight);
pub type TestMessageFee = u64;
pub type TestRelayer = u64;
pub struct AccountIdConverter;
impl sp_runtime::traits::Convert<H256, AccountId> for AccountIdConverter {
fn convert(hash: H256) -> AccountId {
hash.to_low_u64_ne()
}
}
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct TestRuntime;
@@ -106,6 +114,8 @@ impl Trait for TestRuntime {
type InboundMessageFee = TestMessageFee;
type InboundRelayer = TestRelayer;
type AccountIdConverter = AccountIdConverter;
type TargetHeaderChain = TestTargetHeaderChain;
type LaneMessageVerifier = TestLaneMessageVerifier;
type MessageDeliveryAndDispatchPayment = TestMessageDeliveryAndDispatchPayment;
@@ -234,7 +244,11 @@ impl TestMessageDeliveryAndDispatchPayment {
impl MessageDeliveryAndDispatchPayment<AccountId, TestMessageFee> for TestMessageDeliveryAndDispatchPayment {
type Error = &'static str;
fn pay_delivery_and_dispatch_fee(submitter: &AccountId, fee: &TestMessageFee) -> Result<(), Self::Error> {
fn pay_delivery_and_dispatch_fee(
submitter: &AccountId,
fee: &TestMessageFee,
_relayer_fund_account: &AccountId,
) -> Result<(), Self::Error> {
if frame_support::storage::unhashed::get(b":reject-message-fee:") == Some(true) {
return Err(TEST_ERROR);
}
@@ -243,7 +257,12 @@ impl MessageDeliveryAndDispatchPayment<AccountId, TestMessageFee> for TestMessag
Ok(())
}
fn pay_relayer_reward(_confirmation_relayer: &AccountId, relayer: &AccountId, fee: &TestMessageFee) {
fn pay_relayer_reward(
_confirmation_relayer: &AccountId,
relayer: &AccountId,
fee: &TestMessageFee,
_relayer_fund_account: &AccountId,
) {
let key = (b":relayer-reward:", relayer, fee).encode();
frame_support::storage::unhashed::put(&key, &true);
}