Reward relayers for dispatching messages (#385)

* reward relayers for dispatching messages

* clippy

* Update modules/message-lane/src/lib.rs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* added comment

* Update modules/message-lane/src/inbound_lane.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Update modules/message-lane/src/inbound_lane.rs

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* SubmitterId + RelayerId -> AccountId

* add confirmation_relayer arg to pay_relayer_reward

* cargo fmt --all

* removed verify_and_decode_messages_proof from SourceHeaderChain

* &mut self -> RefCell

* Optimize max messages at inbound lane (#418)

* Add tests for checking messages above max limit

Signed-off-by: MaciejBaj <macie.baj@gmail.com>

* Extend the relayers entry of inbound lane by additional msg nonce

Signed-off-by: MaciejBaj <macie.baj@gmail.com>

* Support additional message nonce from inbound relayers

Signed-off-by: MaciejBaj <macie.baj@gmail.com>

* Code format

Signed-off-by: MaciejBaj <macie.baj@gmail.com>

* Merge messages range for highest relayers

* Change unwrap() to ensure() while accessing relayers

* Edit rustdocs for relayers deque at inbound lane data

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Declare additional relayers A & B and use across tests consistently

Signed-off-by: MaciejBaj <macie.baj@gmail.com>

* Remove duplicates and improve naming for inbound lane tests

* Fix test checking max limit per inbound lane

* Correct relayers rewards loop after a proof is received

* Remove redundant check for messages ahead of received range

* Correct grammar at inbound lane tests rustdocs

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>

* Improve code quality of relayers updates 💅

Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Test dispatches above max limit from same relayer

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>

* Fix typo.

Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
Co-authored-by: Tomasz Drwięga <tomusdrw@users.noreply.github.com>
Co-authored-by: Maciej Baj <macie.baj@gmail.com>
Co-authored-by: Tomasz Drwięga <tomasz@parity.io>
This commit is contained in:
Svyatoslav Nikolsky
2020-10-20 13:12:35 +03:00
committed by Bastian Köcher
parent c42023269a
commit bff930d01e
6 changed files with 649 additions and 81 deletions
+69 -10
View File
@@ -18,10 +18,10 @@ use crate::Trait;
use bp_message_lane::{
source_chain::{LaneMessageVerifier, MessageDeliveryAndDispatchPayment, TargetHeaderChain},
target_chain::{DispatchMessage, MessageDispatch, SourceHeaderChain},
LaneId, Message, MessageData, MessageKey, MessageNonce,
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages, SourceHeaderChain},
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce,
};
use codec::Encode;
use codec::{Decode, Encode};
use frame_support::{impl_outer_event, impl_outer_origin, parameter_types, weights::Weight};
use sp_core::H256;
use sp_runtime::{
@@ -29,10 +29,12 @@ use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
Perbill,
};
use std::collections::BTreeMap;
pub type AccountId = u64;
pub type TestPayload = (u64, Weight);
pub type TestMessageFee = u64;
pub type TestRelayer = u64;
#[derive(Clone, Eq, PartialEq, Debug)]
pub struct TestRuntime;
@@ -89,17 +91,20 @@ impl frame_system::Trait for TestRuntime {
parameter_types! {
pub const MaxMessagesToPruneAtOnce: u64 = 10;
pub const MaxUnconfirmedMessagesAtInboundLane: u64 = 16;
}
impl Trait for TestRuntime {
type Event = TestEvent;
type MaxMessagesToPruneAtOnce = MaxMessagesToPruneAtOnce;
type MaxUnconfirmedMessagesAtInboundLane = MaxUnconfirmedMessagesAtInboundLane;
type OutboundPayload = TestPayload;
type OutboundMessageFee = TestMessageFee;
type InboundPayload = TestPayload;
type InboundMessageFee = TestMessageFee;
type InboundRelayer = TestRelayer;
type TargetHeaderChain = TestTargetHeaderChain;
type LaneMessageVerifier = TestLaneMessageVerifier;
@@ -109,6 +114,15 @@ impl Trait for TestRuntime {
type MessageDispatch = TestMessageDispatch;
}
/// Account id of test relayer.
pub const TEST_RELAYER_A: AccountId = 100;
/// Account id of additional test relayer - B.
pub const TEST_RELAYER_B: AccountId = 101;
/// Account id of additional test relayer - C.
pub const TEST_RELAYER_C: AccountId = 102;
/// Error that is returned by all test implementations.
pub const TEST_ERROR: &str = "Test error";
@@ -121,14 +135,42 @@ pub const REGULAR_PAYLOAD: TestPayload = (0, 50);
/// Payload that is rejected by `TestTargetHeaderChain`.
pub const PAYLOAD_REJECTED_BY_TARGET_CHAIN: TestPayload = (1, 50);
/// Vec of proved messages, grouped by lane.
pub type MessagesByLaneVec = Vec<(LaneId, ProvedLaneMessages<Message<TestMessageFee>>)>;
/// Test messages proof.
#[derive(Debug, Encode, Decode, Clone, PartialEq, Eq)]
pub struct TestMessagesProof {
pub result: Result<MessagesByLaneVec, ()>,
}
impl From<Result<Vec<Message<TestMessageFee>>, ()>> for TestMessagesProof {
fn from(result: Result<Vec<Message<TestMessageFee>>, ()>) -> Self {
Self {
result: result.map(|messages| {
let mut messages_by_lane: BTreeMap<LaneId, ProvedLaneMessages<Message<TestMessageFee>>> =
BTreeMap::new();
for message in messages {
messages_by_lane
.entry(message.key.lane_id)
.or_default()
.messages
.push(message);
}
messages_by_lane.into_iter().collect()
}),
}
}
}
/// Target header chain that is used in tests.
#[derive(Debug, Default)]
pub struct TestTargetHeaderChain;
impl TargetHeaderChain<TestPayload> for TestTargetHeaderChain {
impl TargetHeaderChain<TestPayload, TestRelayer> for TestTargetHeaderChain {
type Error = &'static str;
type MessagesDeliveryProof = Result<(LaneId, MessageNonce), ()>;
type MessagesDeliveryProof = Result<(LaneId, InboundLaneData<TestRelayer>), ()>;
fn verify_message(payload: &TestPayload) -> Result<(), Self::Error> {
if *payload == PAYLOAD_REJECTED_BY_TARGET_CHAIN {
@@ -140,7 +182,7 @@ impl TargetHeaderChain<TestPayload> for TestTargetHeaderChain {
fn verify_messages_delivery_proof(
proof: Self::MessagesDeliveryProof,
) -> Result<(LaneId, MessageNonce), Self::Error> {
) -> Result<(LaneId, InboundLaneData<TestRelayer>), Self::Error> {
proof.map_err(|_| TEST_ERROR)
}
}
@@ -176,10 +218,17 @@ impl TestMessageDeliveryAndDispatchPayment {
frame_support::storage::unhashed::put(b":reject-message-fee:", &true);
}
/// Returns true if given fee has been paid by given relayer.
/// Returns true if given fee has been paid by given submitter.
pub fn is_fee_paid(submitter: AccountId, fee: TestMessageFee) -> bool {
frame_support::storage::unhashed::get(b":message-fee:") == Some((submitter, fee))
}
/// Returns true if given relayer has been rewarded with given balance. The reward-paid flag is
/// cleared after the call.
pub fn is_reward_paid(relayer: AccountId, fee: TestMessageFee) -> bool {
let key = (b":relayer-reward:", relayer, fee).encode();
frame_support::storage::unhashed::take::<bool>(&key).is_some()
}
}
impl MessageDeliveryAndDispatchPayment<AccountId, TestMessageFee> for TestMessageDeliveryAndDispatchPayment {
@@ -193,6 +242,11 @@ impl MessageDeliveryAndDispatchPayment<AccountId, TestMessageFee> for TestMessag
frame_support::storage::unhashed::put(b":message-fee:", &(submitter, fee));
Ok(())
}
fn pay_relayer_reward(_confirmation_relayer: &AccountId, relayer: &AccountId, fee: &TestMessageFee) {
let key = (b":relayer-reward:", relayer, fee).encode();
frame_support::storage::unhashed::put(&key, &true);
}
}
/// Source header chain that is used in tests.
@@ -202,10 +256,15 @@ pub struct TestSourceHeaderChain;
impl SourceHeaderChain<TestMessageFee> for TestSourceHeaderChain {
type Error = &'static str;
type MessagesProof = Result<Vec<Message<TestMessageFee>>, ()>;
type MessagesProof = TestMessagesProof;
fn verify_messages_proof(proof: Self::MessagesProof) -> Result<Vec<Message<TestMessageFee>>, Self::Error> {
proof.map_err(|_| TEST_ERROR)
fn verify_messages_proof(
proof: Self::MessagesProof,
) -> Result<ProvedMessages<Message<TestMessageFee>>, Self::Error> {
proof
.result
.map(|proof| proof.into_iter().collect())
.map_err(|_| TEST_ERROR)
}
}