Replace BATCH_CALL_SUPPORTED (#1733)

* Simplify submit_and_watch_signed_extrinsic

The way submit_and_watch_signed_extrinsic is used now, we can always
derive the SignParam from other params. If in the future we need more
customization possibilities, we can define a new method.

* Simplify submit_signed_extrinsic

* Send maybe_batch_tx as a parameter

Send `maybe_batch_tx` as a parameter to `submit_proof()`. This way we
can deduplicate the logic that submits the extrinsic for
`messages_source and `messages_target` and we can simplify the logic in
the race loop a bit.

* Define BatchProofTransaction

Deduplicate BatchConfirmationTransaction and BatchDeliveryTransaction by
replacing both of them with BatchProofTransaction

* Define ChainWithUtilityPallet and BatchCallBuilderConstructor

- Define `ChainWithUtilityPallet` in order to be able to associate the
  batching functionality with chains
- Defining `BatchCallBuilderConstructor` in order to have a more reliable
  way of checking whether an end of a messages pipeline supports batching
  or no. `BatchCallBuilderConstructor::new_builder()` returns an
  `Option<BatchCallBuilder>`.This is a bit safer because each time a caller
  tries to start creating a batch call, it will call `new_builder()` and
  will be required to handle the returned `Option`. Before we only had a
  bool `BATCH_CALL_SUPPORTED` the caller could have forgetten to check.
This commit is contained in:
Serban Iorga
2022-12-27 15:39:23 +02:00
committed by Bastian Köcher
parent df1aed01c4
commit e47f1e42e0
20 changed files with 290 additions and 494 deletions
@@ -111,26 +111,17 @@ pub struct NoncesSubmitArtifacts<T> {
/// Batch transaction that already submit some headers and needs to be extended with
/// messages/delivery proof before sending.
#[async_trait]
pub trait BatchTransaction<HeaderId, Proof, TransactionTracker, Error>: Send {
pub trait BatchTransaction<HeaderId>: Send {
/// Header that was required in the original call and which is bundled within this
/// batch transaction.
fn required_header_id(&self) -> HeaderId;
/// Append proof and send transaction to the connected node.
async fn append_proof_and_send(self, proof: Proof) -> Result<TransactionTracker, Error>;
}
/// Source client trait.
#[async_trait]
pub trait SourceClient<P: MessageLane>: RelayClient {
/// Type of batch transaction that submits finality and message receiving proof.
type BatchTransaction: BatchTransaction<
TargetHeaderIdOf<P>,
P::MessagesReceivingProof,
Self::TransactionTracker,
Self::Error,
>;
type BatchTransaction: BatchTransaction<TargetHeaderIdOf<P>>;
/// Transaction tracker to track submitted transactions.
type TransactionTracker: TransactionTracker<HeaderId = SourceHeaderIdOf<P>>;
@@ -170,6 +161,7 @@ pub trait SourceClient<P: MessageLane>: RelayClient {
/// Submit messages receiving proof.
async fn submit_messages_receiving_proof(
&self,
maybe_batch_tx: Option<Self::BatchTransaction>,
generated_at_block: TargetHeaderIdOf<P>,
proof: P::MessagesReceivingProof,
) -> Result<Self::TransactionTracker, Self::Error>;
@@ -194,12 +186,7 @@ pub trait SourceClient<P: MessageLane>: RelayClient {
#[async_trait]
pub trait TargetClient<P: MessageLane>: RelayClient {
/// Type of batch transaction that submits finality and messages proof.
type BatchTransaction: BatchTransaction<
SourceHeaderIdOf<P>,
P::MessagesProof,
Self::TransactionTracker,
Self::Error,
>;
type BatchTransaction: BatchTransaction<SourceHeaderIdOf<P>>;
/// Transaction tracker to track submitted transactions.
type TransactionTracker: TransactionTracker<HeaderId = TargetHeaderIdOf<P>>;
@@ -233,6 +220,7 @@ pub trait TargetClient<P: MessageLane>: RelayClient {
/// Submit messages proof.
async fn submit_messages_proof(
&self,
maybe_batch_tx: Option<Self::BatchTransaction>,
generated_at_header: SourceHeaderIdOf<P>,
nonces: RangeInclusive<MessageNonce>,
proof: P::MessagesProof,
@@ -533,57 +521,26 @@ pub(crate) mod tests {
#[derive(Clone, Debug)]
pub struct TestMessagesBatchTransaction {
data: Arc<Mutex<TestClientData>>,
required_header_id: TestSourceHeaderId,
tx_tracker: TestTransactionTracker,
}
#[async_trait]
impl BatchTransaction<TestSourceHeaderId, TestMessagesProof, TestTransactionTracker, TestError>
for TestMessagesBatchTransaction
{
impl BatchTransaction<TestSourceHeaderId> for TestMessagesBatchTransaction {
fn required_header_id(&self) -> TestSourceHeaderId {
self.required_header_id
}
async fn append_proof_and_send(
self,
proof: TestMessagesProof,
) -> Result<TestTransactionTracker, TestError> {
let mut data = self.data.lock();
data.receive_messages(proof);
Ok(self.tx_tracker)
}
}
#[derive(Clone, Debug)]
pub struct TestConfirmationBatchTransaction {
data: Arc<Mutex<TestClientData>>,
required_header_id: TestTargetHeaderId,
tx_tracker: TestTransactionTracker,
}
#[async_trait]
impl
BatchTransaction<
TestTargetHeaderId,
TestMessagesReceivingProof,
TestTransactionTracker,
TestError,
> for TestConfirmationBatchTransaction
{
impl BatchTransaction<TestTargetHeaderId> for TestConfirmationBatchTransaction {
fn required_header_id(&self) -> TestTargetHeaderId {
self.required_header_id
}
async fn append_proof_and_send(
self,
proof: TestMessagesReceivingProof,
) -> Result<TestTransactionTracker, TestError> {
let mut data = self.data.lock();
data.receive_messages_delivery_proof(proof);
Ok(self.tx_tracker)
}
}
#[derive(Clone, Debug)]
@@ -800,6 +757,7 @@ pub(crate) mod tests {
async fn submit_messages_receiving_proof(
&self,
_maybe_batch_tx: Option<Self::BatchTransaction>,
_generated_at_block: TargetHeaderIdOf<TestMessageLane>,
proof: TestMessagesReceivingProof,
) -> Result<Self::TransactionTracker, TestError> {
@@ -924,6 +882,7 @@ pub(crate) mod tests {
async fn submit_messages_proof(
&self,
_maybe_batch_tx: Option<Self::BatchTransaction>,
_generated_at_header: SourceHeaderIdOf<TestMessageLane>,
nonces: RangeInclusive<MessageNonce>,
proof: TestMessagesProof,
@@ -1287,8 +1246,6 @@ pub(crate) mod tests {
target_latest_received_nonce: 0,
..Default::default()
}));
let target_original_data = original_data.clone();
let source_original_data = original_data.clone();
let result = run_loop_test(
original_data,
Arc::new(|_| {}),
@@ -1298,9 +1255,7 @@ pub(crate) mod tests {
{
data.target_to_source_batch_transaction =
Some(TestConfirmationBatchTransaction {
data: source_original_data.clone(),
required_header_id: target_to_source_header_required,
tx_tracker: TestTransactionTracker::default(),
})
}
}),
@@ -1310,9 +1265,7 @@ pub(crate) mod tests {
data.source_to_target_header_required.take()
{
data.source_to_target_batch_transaction = Some(TestMessagesBatchTransaction {
data: target_original_data.clone(),
required_header_id: source_to_target_header_required,
tx_tracker: TestTransactionTracker::default(),
})
}
@@ -214,11 +214,14 @@ where
async fn submit_proof(
&self,
maybe_batch_tx: Option<Self::BatchTransaction>,
generated_at_block: SourceHeaderIdOf<P>,
nonces: RangeInclusive<MessageNonce>,
proof: P::MessagesProof,
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
self.client.submit_messages_proof(generated_at_block, nonces, proof).await
self.client
.submit_messages_proof(maybe_batch_tx, generated_at_block, nonces, proof)
.await
}
}
@@ -128,12 +128,7 @@ pub trait TargetClient<P: MessageRace> {
/// Type of the additional data from the target client, used by the race.
type TargetNoncesData: std::fmt::Debug;
/// Type of batch transaction that submits finality and proof to the target node.
type BatchTransaction: BatchTransaction<
P::SourceHeaderId,
P::Proof,
Self::TransactionTracker,
Self::Error,
>;
type BatchTransaction: BatchTransaction<P::SourceHeaderId>;
/// Transaction tracker to track submitted transactions.
type TransactionTracker: TransactionTracker<HeaderId = P::TargetHeaderId>;
@@ -160,6 +155,7 @@ pub trait TargetClient<P: MessageRace> {
/// Submit proof to the target client.
async fn submit_proof(
&self,
maybe_batch_tx: Option<Self::BatchTransaction>,
generated_at_block: P::SourceHeaderId,
nonces: RangeInclusive<MessageNonce>,
proof: P::Proof,
@@ -575,41 +571,30 @@ pub async fn run<P: MessageRace, SC: SourceClient<P>, TC: TargetClient<P>>(
target_client_is_online = false;
if let Some((at_block, nonces_range, proof)) = race_state.nonces_to_submit.as_ref() {
if let Some(target_batch_transaction) = target_batch_transaction.take() {
log::debug!(
target: "bridge",
"Going to submit proof of messages in range {:?} to {} node",
nonces_range,
P::target_name(),
);
if let Some(ref target_batch_transaction) = target_batch_transaction {
log::debug!(
target: "bridge",
"Going to submit batch transaction with header {:?} and proof of messages in range {:?} to {} node",
"This transaction is batched with sending the proof for header {:?}.",
target_batch_transaction.required_header_id(),
nonces_range,
P::target_name(),
);
let nonces = nonces_range.clone();
target_submit_proof.set(
target_batch_transaction
.append_proof_and_send(proof.clone())
.map(|result| {
result
.map(|tx_tracker| NoncesSubmitArtifacts { nonces, tx_tracker })
})
.left_future()
.fuse(),
);
} else {
log::debug!(
target: "bridge",
"Going to submit proof of messages in range {:?} to {} node",
nonces_range,
P::target_name(),
);
target_submit_proof.set(
race_target
.submit_proof(at_block.clone(), nonces_range.clone(), proof.clone())
.right_future()
.fuse(),
);
}
target_submit_proof.set(
race_target
.submit_proof(
target_batch_transaction.take(),
at_block.clone(),
nonces_range.clone(),
proof.clone(),
)
.fuse(),
);
} else if let Some(source_required_header) = source_required_header.clone() {
log::debug!(target: "bridge", "Going to require {} header {:?} at {}", P::source_name(), source_required_header, P::target_name());
target_require_source_header
@@ -182,12 +182,15 @@ where
async fn submit_proof(
&self,
maybe_batch_tx: Option<Self::BatchTransaction>,
generated_at_block: TargetHeaderIdOf<P>,
nonces: RangeInclusive<MessageNonce>,
proof: P::MessagesReceivingProof,
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
let tx_tracker =
self.client.submit_messages_receiving_proof(generated_at_block, proof).await?;
let tx_tracker = self
.client
.submit_messages_receiving_proof(maybe_batch_tx, generated_at_block, proof)
.await?;
Ok(NoncesSubmitArtifacts { nonces, tx_tracker })
}
}