Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Batch transactions in complex relays #1669

Merged
merged 32 commits into from
Dec 16, 2022
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4c3cc6b
batch transactions in message relay: API prototype
svyatonik Nov 29, 2022
e140e11
get rid of Box<dyn BatchTransaction> and actually submit it
svyatonik Nov 30, 2022
feba6fa
test batch transactions
svyatonik Nov 30, 2022
e372820
message_lane_loop_works_with_batch_transactions
svyatonik Nov 30, 2022
824fc23
removed logger
svyatonik Nov 30, 2022
f8730aa
BatchConfirmationTransaction + BatchDeliveryTransaction
svyatonik Dec 1, 2022
9cc4fe3
more prototyping
svyatonik Dec 1, 2022
14c1aa8
fmt
svyatonik Dec 1, 2022
418d6e4
continue with batch calls
svyatonik Dec 1, 2022
0dcdec8
impl BatchCallBuilder for ()
svyatonik Dec 1, 2022
d32fb4d
BatchDeliveryTransaction impl
svyatonik Dec 1, 2022
b265949
BundledBatchCallBuilder
svyatonik Dec 12, 2022
8cddd6a
Merge branch 'master' into batch-transactions-in-message-relay
svyatonik Dec 12, 2022
ac59ecc
proper impl of BundledBatchCallBuilder + use it in RialtoParachain ->…
svyatonik Dec 12, 2022
cfa95c1
impl prove_header in OnDemandHeadersRelay
svyatonik Dec 12, 2022
9e850d2
impl OnDemandParachainsRelay::prove_header (needs extensive tests)
svyatonik Dec 12, 2022
b0a277b
added a couple of TODOs
svyatonik Dec 12, 2022
a1c50d6
return Result<Option<BatchTx>> when asking for more headers
svyatonik Dec 13, 2022
b852158
prove headers when reauire_* is called && return proper headers from …
svyatonik Dec 13, 2022
38561c0
split parachains::prove_header and test select_headers_to_prove
svyatonik Dec 13, 2022
c1dff4b
more traces and leave TODOs
svyatonik Dec 14, 2022
2d8b500
use finality stream in SubstrateFinalitySource::prove_block_finality
svyatonik Dec 14, 2022
fad8069
prove parachain head at block, selected by headers relay
svyatonik Dec 14, 2022
5053b16
const ANCIENT_BLOCK_THRESHOLD
svyatonik Dec 14, 2022
b5f2623
TODO -> proof
svyatonik Dec 14, 2022
aec2063
clippy and spelling
svyatonik Dec 14, 2022
21fbb0c
Merge branch 'master' into batch-transactions-in-message-relay
svyatonik Dec 14, 2022
0dc01ab
BatchCallBuilder::build_batch_call() returns Result
svyatonik Dec 15, 2022
8370c50
Merge branch 'master' into batch-transactions-in-message-relay
svyatonik Dec 15, 2022
d1254fc
read first proof from two streams
svyatonik Dec 15, 2022
78d5214
FailedToFindFinalityProof -> FinalityProofNotFound
svyatonik Dec 16, 2022
9da39c7
changed select_headers_to_prove to version from PR review
svyatonik Dec 16, 2022
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
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,7 @@ impl SubstrateMessageLane for BridgeHubRococoMessagesToBridgeHubWococoMessageLan
BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
BridgeHubRococoMessagesToBridgeHubWococoMessageLaneReceiveMessagesDeliveryProofCallBuilder;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,7 @@ impl SubstrateMessageLane for BridgeHubWococoMessagesToBridgeHubRococoMessageLan
BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesProofCallBuilder;
type ReceiveMessagesDeliveryProofCallBuilder =
BridgeHubWococoMessagesToBridgeHubRococoMessageLaneReceiveMessagesDeliveryProofCallBuilder;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
3 changes: 3 additions & 0 deletions relays/bin-substrate/src/chains/millau_messages_to_rialto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
millau_runtime::Runtime,
millau_runtime::WithRialtoMessagesInstance,
>;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ impl SubstrateMessageLane for MillauMessagesToRialtoParachain {
millau_runtime::Runtime,
millau_runtime::WithRialtoParachainMessagesInstance,
>;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
3 changes: 3 additions & 0 deletions relays/bin-substrate/src/chains/rialto_messages_to_millau.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,7 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
rialto_runtime::Runtime,
rialto_runtime::WithMillauMessagesInstance,
>;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = ();
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@

use relay_millau_client::Millau;
use relay_rialto_parachain_client::RialtoParachain;
use substrate_relay_helper::messages_lane::{
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
SubstrateMessageLane,
use substrate_relay_helper::{
messages_lane::{
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
SubstrateMessageLane,
},
BundledBatchCallBuilder,
};

/// Description of RialtoParachain -> Millau messages bridge.
Expand All @@ -41,4 +44,7 @@ impl SubstrateMessageLane for RialtoParachainMessagesToMillau {
rialto_parachain_runtime::Runtime,
rialto_parachain_runtime::WithMillauMessagesInstance,
>;

type SourceBatchCallBuilder = ();
type TargetBatchCallBuilder = BundledBatchCallBuilder<millau_runtime::Runtime>;
}
10 changes: 5 additions & 5 deletions relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ use crate::{
declare_chain_cli_schema,
};
use bp_messages::LaneId;
use bp_runtime::{BalanceOf, BlockNumberOf};
use bp_runtime::BalanceOf;
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithTransactions, Client,
Parachain,
Expand Down Expand Up @@ -167,8 +167,8 @@ where
/// Returns message relay parameters.
fn messages_relay_params(
&self,
source_to_target_headers_relay: Arc<dyn OnDemandRelay<BlockNumberOf<Source>>>,
target_to_source_headers_relay: Arc<dyn OnDemandRelay<BlockNumberOf<Target>>>,
source_to_target_headers_relay: Arc<dyn OnDemandRelay<Source, Target>>,
target_to_source_headers_relay: Arc<dyn OnDemandRelay<Target, Source>>,
lane_id: LaneId,
) -> MessagesRelayParams<Bridge::MessagesLane> {
MessagesRelayParams {
Expand Down Expand Up @@ -243,8 +243,8 @@ trait Full2WayBridgeBase: Sized + Send + Sync {
async fn start_on_demand_headers_relayers(
&mut self,
) -> anyhow::Result<(
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)>;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ use crate::cli::{
CliChain,
};
use bp_polkadot_core::parachains::ParaHash;
use bp_runtime::BlockNumberOf;
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
Expand Down Expand Up @@ -215,8 +214,8 @@ where
async fn start_on_demand_headers_relayers(
&mut self,
) -> anyhow::Result<(
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.left.accounts.push(TaggedAccount::Headers {
id: self.right_headers_to_left_transaction_params.signer.public().into(),
Expand Down Expand Up @@ -249,31 +248,31 @@ where
.await?;

let left_relay_to_right_on_demand_headers =
OnDemandHeadersRelay::new::<<L2R as ParachainToRelayHeadersCliBridge>::RelayFinality>(
OnDemandHeadersRelay::<<L2R as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.left_relay.clone(),
self.common.right.client.clone(),
self.left_headers_to_right_transaction_params.clone(),
self.common.shared.only_mandatory_headers,
);
let right_relay_to_left_on_demand_headers =
OnDemandHeadersRelay::new::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>(
OnDemandHeadersRelay::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_headers_to_left_transaction_params.clone(),
self.common.shared.only_mandatory_headers,
);

let left_to_right_on_demand_parachains = OnDemandParachainsRelay::new::<
let left_to_right_on_demand_parachains = OnDemandParachainsRelay::<
<L2R as ParachainToRelayHeadersCliBridge>::ParachainFinality,
>(
>::new(
self.left_relay.clone(),
self.common.right.client.clone(),
self.left_parachains_to_right_transaction_params.clone(),
Arc::new(left_relay_to_right_on_demand_headers),
);
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::new::<
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::<
<R2L as ParachainToRelayHeadersCliBridge>::ParachainFinality,
>(
>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_parachains_to_left_transaction_params.clone(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ use crate::cli::{
CliChain,
};
use bp_polkadot_core::parachains::ParaHash;
use bp_runtime::BlockNumberOf;
use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
use relay_substrate_client::{
AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
Expand Down Expand Up @@ -199,8 +198,8 @@ where
async fn start_on_demand_headers_relayers(
&mut self,
) -> anyhow::Result<(
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.left.accounts.push(TaggedAccount::Headers {
id: self.right_headers_to_left_transaction_params.signer.public().into(),
Expand Down Expand Up @@ -229,22 +228,22 @@ where
.await?;

let left_to_right_on_demand_headers =
OnDemandHeadersRelay::new::<<L2R as RelayToRelayHeadersCliBridge>::Finality>(
OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.left.client.clone(),
self.common.right.client.clone(),
self.left_headers_to_right_transaction_params.clone(),
self.common.shared.only_mandatory_headers,
);
let right_relay_to_left_on_demand_headers =
OnDemandHeadersRelay::new::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>(
OnDemandHeadersRelay::<<R2L as ParachainToRelayHeadersCliBridge>::RelayFinality>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_headers_to_left_transaction_params.clone(),
self.common.shared.only_mandatory_headers,
);
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::new::<
let right_to_left_on_demand_parachains = OnDemandParachainsRelay::<
<R2L as ParachainToRelayHeadersCliBridge>::ParachainFinality,
>(
>::new(
self.right_relay.clone(),
self.common.left.client.clone(),
self.right_parachains_to_left_transaction_params.clone(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ use crate::cli::{
relay_headers_and_messages::{Full2WayBridgeBase, Full2WayBridgeCommonParams},
CliChain,
};
use bp_runtime::BlockNumberOf;
use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, ChainWithTransactions};
use sp_core::Pair;
use substrate_relay_helper::{
Expand Down Expand Up @@ -149,8 +148,8 @@ where
async fn start_on_demand_headers_relayers(
&mut self,
) -> anyhow::Result<(
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Left>>>,
Arc<dyn OnDemandRelay<BlockNumberOf<Self::Right>>>,
Arc<dyn OnDemandRelay<Self::Left, Self::Right>>,
Arc<dyn OnDemandRelay<Self::Right, Self::Left>>,
)> {
self.common.right.accounts.push(TaggedAccount::Headers {
id: self.left_to_right_transaction_params.signer.public().into(),
Expand All @@ -175,14 +174,14 @@ where
.await?;

let left_to_right_on_demand_headers =
OnDemandHeadersRelay::new::<<L2R as RelayToRelayHeadersCliBridge>::Finality>(
OnDemandHeadersRelay::<<L2R as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.left.client.clone(),
self.common.right.client.clone(),
self.left_to_right_transaction_params.clone(),
self.common.shared.only_mandatory_headers,
);
let right_to_left_on_demand_headers =
OnDemandHeadersRelay::new::<<R2L as RelayToRelayHeadersCliBridge>::Finality>(
OnDemandHeadersRelay::<<R2L as RelayToRelayHeadersCliBridge>::Finality>::new(
self.common.right.client.clone(),
self.common.left.client.clone(),
self.right_to_left_transaction_params.clone(),
Expand Down
1 change: 1 addition & 0 deletions relays/client-substrate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ thiserror = "1.0.26"

bp-header-chain = { path = "../../primitives/header-chain" }
bp-messages = { path = "../../primitives/messages" }
bp-polkadot-core = { path = "../../primitives/polkadot-core" }
bp-runtime = { path = "../../primitives/runtime" }
pallet-bridge-messages = { path = "../../modules/messages" }
finality-relay = { path = "../finality" }
Expand Down
12 changes: 12 additions & 0 deletions relays/client-substrate/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,18 @@ const SUB_API_GRANDPA_AUTHORITIES: &str = "GrandpaApi_grandpa_authorities";
const SUB_API_TXPOOL_VALIDATE_TRANSACTION: &str = "TaggedTransactionQueue_validate_transaction";
const MAX_SUBSCRIPTION_CAPACITY: usize = 4096;

/// The difference between best block number and number of its ancestor, that is enough
/// for us to consider that ancestor an "ancient" block with dropped state.
///
/// The relay does not assume that it is connected to the archive node, so it always tries
/// to use the best available chain state. But sometimes it still may use state of some
/// old block. If the state of that block is already dropped, relay will see errors when
/// e.g. it tries to prove something.
///
/// By default Substrate-based nodes are storing state for last 256 blocks. We'll use
/// half of this value.
pub const ANCIENT_BLOCK_THRESHOLD: u32 = 128;

/// Opaque justifications subscription type.
pub struct Subscription<T>(pub(crate) Mutex<futures::channel::mpsc::Receiver<Option<T>>>);

Expand Down
7 changes: 7 additions & 0 deletions relays/client-substrate/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

//! Substrate node RPC errors.

use bp_polkadot_core::parachains::ParaId;
use jsonrpsee::core::Error as RpcError;
use relay_utils::MaybeConnectionError;
use sc_rpc_api::system::Health;
Expand Down Expand Up @@ -45,6 +46,12 @@ pub enum Error {
/// Runtime storage is missing some mandatory value.
#[error("Mandatory storage value is missing from the runtime storage.")]
MissingMandatoryStorageValue,
/// Required parachain head is not present at the relay chain.
#[error("Parachain {0:?} head {1} is missing from the relay chain storage.")]
MissingRequiredParachainHead(ParaId, u64),
/// Failed to find finality proof for the given header.
#[error("Failed to find finality proof for header {0}.")]
FailedToFindFinalityProof(u64),
/// The client we're connected to is not synced, so we can't rely on its state.
#[error("Substrate client is not synced {0}.")]
ClientNotSynced(Health),
Expand Down
5 changes: 4 additions & 1 deletion relays/client-substrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ pub use crate::{
ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, Parachain, RelayChain,
SignParam, TransactionStatusOf, UnsignedTransaction,
},
client::{ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription},
client::{
ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription,
ANCIENT_BLOCK_THRESHOLD,
},
error::{Error, Result},
rpc::{SubstrateBeefyFinalityClient, SubstrateFinalityClient, SubstrateGrandpaFinalityClient},
sync_header::SyncHeader,
Expand Down
1 change: 1 addition & 0 deletions relays/lib-substrate-relay/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ bp-messages = { path = "../../primitives/messages" }
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-finality-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master" }
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
Expand Down
54 changes: 53 additions & 1 deletion relays/lib-substrate-relay/src/finality/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ use crate::finality::{engine::Engine, FinalitySyncPipelineAdapter, SubstrateFina

use async_std::sync::{Arc, Mutex};
use async_trait::async_trait;
use bp_header_chain::FinalityProof;
use codec::Decode;
use finality_relay::SourceClient;
use futures::stream::{unfold, Stream, StreamExt};
use num_traits::One;
use relay_substrate_client::{
BlockNumberOf, BlockWithJustification, Chain, Client, Error, HeaderOf,
};
use relay_utils::relay_loop::Client as RelayClient;
use relay_utils::{relay_loop::Client as RelayClient, UniqueSaturatedInto};
use std::pin::Pin;

/// Shared updatable reference to the maximal header number that we want to sync from the source.
Expand Down Expand Up @@ -70,6 +72,56 @@ impl<P: SubstrateFinalitySyncPipeline> SubstrateFinalitySource<P> {
// target node may be missing proofs that are already available at the source
self.client.best_finalized_header_number().await
}

/// Return header and its justification of the given block or its earlier descendant that
/// has a GRANDPA justification.
///
/// This method is optimized for cases when `block_number` is close to the best finalized
/// chain block.
pub async fn prove_block_finality(
&self,
block_number: BlockNumberOf<P::SourceChain>,
) -> Result<
(relay_substrate_client::SyncHeader<HeaderOf<P::SourceChain>>, SubstrateFinalityProof<P>),
Error,
> {
// when we talk about GRANDPA finality:
//
// only mandatory headers have persistent notifications (that are returned by the
// `header_and_finality_proof` call). Since this method is supposed to work with arbitrary
// headers, we can't rely only on persistent justifications. So let's start with subscribing
// to ephemeral justifications to avoid waiting too much if we have failed to find
// persistent one.
let best_finalized_block_number = self.client.best_finalized_header_number().await?;
let mut finality_proofs = self.finality_proofs().await?;

// start searching for persistent justificaitons
let mut current_block_number = block_number;
while current_block_number <= best_finalized_block_number {
let (header, maybe_proof) =
self.header_and_finality_proof(current_block_number).await?;
match maybe_proof {
Some(proof) => return Ok((header, proof)),
None => {
current_block_number += One::one();
},
}
}

// we have failed to find persistent justification, so let's try with ephemeral
while let Some(proof) = finality_proofs.next().await {
// this is just for safety, in practice we shall never get notifications for earlier
// headers here (if `block_number <= best_finalized_block_number` of course)
if proof.target_header_number() < block_number {
continue
}

let header = self.client.header_by_number(proof.target_header_number()).await?;
return Ok((header.into(), proof))
}

Err(Error::FailedToFindFinalityProof(block_number.unique_saturated_into()))
}
}

impl<P: SubstrateFinalitySyncPipeline> Clone for SubstrateFinalitySource<P> {
Expand Down
Loading