Skip to content

Commit

Permalink
Batch transactions in complex relays (#1669)
Browse files Browse the repository at this point in the history
* batch transactions in message relay: API prototype

* get rid of Box<dyn BatchTransaction> and actually submit it

* test batch transactions

* message_lane_loop_works_with_batch_transactions

* removed logger

* BatchConfirmationTransaction + BatchDeliveryTransaction

* more prototyping

* fmt

* continue with batch calls

* impl BatchCallBuilder for ()

* BatchDeliveryTransaction impl

* BundledBatchCallBuilder

* proper impl of BundledBatchCallBuilder + use it in RialtoParachain -> Millau

* impl prove_header in OnDemandHeadersRelay

* impl OnDemandParachainsRelay::prove_header (needs extensive tests)

* added a couple of TODOs

* return Result<Option<BatchTx>> when asking for more headers

* prove headers when reauire_* is called && return proper headers from required_header_id

* split parachains::prove_header and test select_headers_to_prove

* more traces and leave TODOs

* use finality stream in SubstrateFinalitySource::prove_block_finality

* prove parachain head at block, selected by headers relay

* const ANCIENT_BLOCK_THRESHOLD

* TODO -> proof

* clippy and spelling

* BatchCallBuilder::build_batch_call() returns Result

* read first proof from two streams

* FailedToFindFinalityProof -> FinalityProofNotFound

* changed select_headers_to_prove to version from PR review
  • Loading branch information
svyatonik authored and bkchr committed Apr 10, 2024
1 parent a732a04 commit be27bd5
Show file tree
Hide file tree
Showing 28 changed files with 1,189 additions and 151 deletions.
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 = ();
}
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 = ();
}
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>;
}
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 bridges/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 bridges/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 bridges/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}.")]
FinalityProofNotFound(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 bridges/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 bridges/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
Loading

0 comments on commit be27bd5

Please sign in to comment.