Skip to content

Commit

Permalink
Merge pull request #2186 from subspace/bundle-check
Browse files Browse the repository at this point in the history
Double check the domain transaction validity before putting it into bundle
  • Loading branch information
NingLin-P authored Nov 1, 2023
2 parents cdcf885 + 668b967 commit c0f905f
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 29 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions domains/client/domain-operator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ sp-keystore = { version = "0.27.0", git = "https://github.com/subspace/polkadot-
sp-messenger = { version = "0.1.0", path = "../../primitives/messenger" }
sp-runtime = { version = "24.0.0", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-state-machine = { version = "0.28.0", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-transaction-pool = { version = "4.0.0-dev", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-trie = { version = "22.0.0", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
sp-weights = { version = "20.0.0", git = "https://github.com/subspace/polkadot-sdk", rev = "892bf8e938c6bd2b893d3827d1093cd81baa59a1" }
subspace-core-primitives = { version = "0.1.0", path = "../../../crates/subspace-core-primitives" }
Expand Down
3 changes: 2 additions & 1 deletion domains/client/domain-operator/src/domain_bundle_producer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use sp_domains::{
use sp_keystore::KeystorePtr;
use sp_runtime::traits::{Block as BlockT, Zero};
use sp_runtime::RuntimeAppPublic;
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use std::convert::{AsRef, Into};
use std::marker::PhantomData;
use std::sync::Arc;
Expand Down Expand Up @@ -101,7 +102,7 @@ where
NumberFor<Block>: Into<NumberFor<CBlock>>,
NumberFor<ParentChainBlock>: Into<NumberFor<Block>>,
Client: HeaderBackend<Block> + BlockBackend<Block> + AuxStore + ProvideRuntimeApi<Block>,
Client::Api: BlockBuilder<Block> + DomainCoreApi<Block>,
Client::Api: BlockBuilder<Block> + DomainCoreApi<Block> + TaggedTransactionQueue<Block>,
CClient: HeaderBackend<CBlock> + ProvideRuntimeApi<CBlock>,
CClient::Api: DomainsApi<CBlock, Block::Header> + BundleProducerElectionApi<CBlock, Balance>,
ParentChain: ParentChainInterface<Block, ParentChainBlock> + Clone,
Expand Down
80 changes: 54 additions & 26 deletions domains/client/domain-operator/src/domain_bundle_proposer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ use codec::Encode;
use domain_runtime_primitives::DomainCoreApi;
use futures::{select, FutureExt};
use sc_client_api::{AuxStore, BlockBackend};
use sc_transaction_pool_api::InPoolTransaction;
use sc_transaction_pool_api::{InPoolTransaction, TransactionSource};
use sp_api::{HeaderT, NumberFor, ProvideRuntimeApi};
use sp_block_builder::BlockBuilder;
use sp_blockchain::HeaderBackend;
use sp_domains::{BundleHeader, ExecutionReceipt, HeaderHashingFor, ProofOfElection};
use sp_runtime::traits::{Block as BlockT, Hash as HashT, One, Zero};
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use sp_weights::Weight;
use std::marker::PhantomData;
use std::sync::Arc;
Expand Down Expand Up @@ -49,7 +50,7 @@ where
CBlock: BlockT,
NumberFor<Block>: Into<NumberFor<CBlock>>,
Client: HeaderBackend<Block> + BlockBackend<Block> + AuxStore + ProvideRuntimeApi<Block>,
Client::Api: BlockBuilder<Block> + DomainCoreApi<Block>,
Client::Api: BlockBuilder<Block> + DomainCoreApi<Block> + TaggedTransactionQueue<Block>,
CClient: HeaderBackend<CBlock>,
TransactionPool: sc_transaction_pool_api::TransactionPool<Block = Block>,
{
Expand Down Expand Up @@ -114,32 +115,59 @@ where
);
})
.unwrap_or(false);
if !is_within_tx_range {
continue;
}

// Double check the transaction validity, because the tx pool are re-validate the transaction
// in pool asynchronously so there is race condition that the operator imported a domain block
// and start producing bundle immediately before the re-validation based on the latest block
// is finished, cause the bundle contains illegal tx accidentally and being considered as invalid
// bundle and slashing on the honest operator.
//
// NOTE: this check need to be kept aligned with how the illegal tx is detected in the block-preprocessor
// thus when https://github.com/subspace/subspace/issues/2184 is implemented, we also need to
// perfome the check for bundle as a whole instead of checking tx one by one.
let transaction_validity = self
.client
.runtime_api()
.validate_transaction(
parent_hash,
TransactionSource::External,
pending_tx_data.clone(),
parent_hash,
)
.map_err(|error| {
sp_blockchain::Error::Application(Box::from(format!(
"Error getting transaction validity: {error}"
)))
})?;
if transaction_validity.is_err() {
continue;
}

if is_within_tx_range {
let tx_weight = self
.client
.runtime_api()
.extrinsic_weight(parent_hash, pending_tx_data)
.map_err(|error| {
sp_blockchain::Error::Application(Box::from(format!(
"Error getting extrinsic weight: {error}"
)))
})?;
let next_estimated_bundle_weight =
estimated_bundle_weight.saturating_add(tx_weight);
if next_estimated_bundle_weight.any_gt(domain_block_limit.max_block_weight) {
break;
}

let next_bundle_size = bundle_size + pending_tx_data.encoded_size() as u32;
if next_bundle_size > domain_block_limit.max_block_size {
break;
}

estimated_bundle_weight = next_estimated_bundle_weight;
bundle_size = next_bundle_size;
extrinsics.push(pending_tx_data.clone());
let tx_weight = self
.client
.runtime_api()
.extrinsic_weight(parent_hash, pending_tx_data)
.map_err(|error| {
sp_blockchain::Error::Application(Box::from(format!(
"Error getting extrinsic weight: {error}"
)))
})?;
let next_estimated_bundle_weight = estimated_bundle_weight.saturating_add(tx_weight);
if next_estimated_bundle_weight.any_gt(domain_block_limit.max_block_weight) {
break;
}

let next_bundle_size = bundle_size + pending_tx_data.encoded_size() as u32;
if next_bundle_size > domain_block_limit.max_block_size {
break;
}

estimated_bundle_weight = next_estimated_bundle_weight;
bundle_size = next_bundle_size;
extrinsics.push(pending_tx_data.clone());
}

let extrinsics_root = HeaderHashingFor::<Block::Header>::ordered_trie_root(
Expand Down
4 changes: 3 additions & 1 deletion domains/client/domain-operator/src/domain_worker_starter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ use sp_core::H256;
use sp_domains::{BundleProducerElectionApi, DomainsApi};
use sp_messenger::MessengerApi;
use sp_runtime::traits::NumberFor;
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use std::sync::Arc;
use subspace_runtime_primitives::Balance;
use tracing::{info, Instrument};
Expand Down Expand Up @@ -84,7 +85,8 @@ pub(super) async fn start_worker<
Client::Api: DomainCoreApi<Block>
+ MessengerApi<Block, NumberFor<Block>>
+ BlockBuilder<Block>
+ sp_api::ApiExt<Block>,
+ sp_api::ApiExt<Block>
+ TaggedTransactionQueue<Block>,
CClient: HeaderBackend<CBlock>
+ HeaderMetadata<CBlock, Error = sp_blockchain::Error>
+ BlockBackend<CBlock>
Expand Down
4 changes: 3 additions & 1 deletion domains/client/domain-operator/src/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use sp_core::H256;
use sp_domains::{BundleProducerElectionApi, DomainsApi};
use sp_messenger::MessengerApi;
use sp_runtime::traits::{Block as BlockT, NumberFor};
use sp_transaction_pool::runtime_api::TaggedTransactionQueue;
use std::sync::Arc;
use subspace_runtime_primitives::Balance;

Expand Down Expand Up @@ -74,7 +75,8 @@ where
Client::Api: DomainCoreApi<Block>
+ MessengerApi<Block, NumberFor<Block>>
+ sp_block_builder::BlockBuilder<Block>
+ sp_api::ApiExt<Block>,
+ sp_api::ApiExt<Block>
+ TaggedTransactionQueue<Block>,
CClient: HeaderBackend<CBlock>
+ HeaderMetadata<CBlock, Error = sp_blockchain::Error>
+ BlockBackend<CBlock>
Expand Down

0 comments on commit c0f905f

Please sign in to comment.