[WIP] txpool (tx validation) using block sums for full validation (#1567)

tx validation (txpool) rework/simplify
This commit is contained in:
Antioch Peverell
2018-09-24 09:24:10 +01:00
committed by GitHub
parent 82b785282c
commit e72d8b58e4
22 changed files with 521 additions and 712 deletions
+24 -22
View File
@@ -27,7 +27,7 @@ use common::types::{self, ChainValidationMode, ServerConfig, SyncState, SyncStat
use core::core::hash::{Hash, Hashed};
use core::core::transaction::Transaction;
use core::core::verifier_cache::VerifierCache;
use core::core::{BlockHeader, CompactBlock};
use core::core::{BlockHeader, BlockSums, CompactBlock};
use core::pow::Difficulty;
use core::{core, global};
use p2p;
@@ -46,7 +46,7 @@ fn wo<T>(weak_one: &OneTime<Weak<T>>) -> Arc<T> {
w(weak_one.borrow().deref())
}
/// Implementation of the NetAdapter for the blockchain. Gets notified when new
/// Implementation of the NetAdapter for the . Gets notified when new
/// blocks and transactions are received and forwards to the chain and pool
/// implementations.
pub struct NetToChainAdapter {
@@ -80,7 +80,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
};
let tx_hash = tx.hash();
let block_hash = w(&self.chain).head_header().unwrap().hash();
let header = w(&self.chain).head_header().unwrap();
debug!(
LOGGER,
@@ -93,7 +93,7 @@ impl p2p::ChainAdapter for NetToChainAdapter {
let res = {
let mut tx_pool = self.tx_pool.write().unwrap();
tx_pool.add_to_pool(source, tx, stem, &block_hash)
tx_pool.add_to_pool(source, tx, stem, &header)
};
if let Err(e) = res {
@@ -617,7 +617,7 @@ impl NetToChainAdapter {
}
/// Implementation of the ChainAdapter for the network. Gets notified when the
/// blockchain accepted a new block, asking the pool to update its state and
/// accepted a new block, asking the pool to update its state and
/// the network to broadcast the block
pub struct ChainToPoolAndNetAdapter {
sync_state: Arc<SyncState>,
@@ -708,7 +708,7 @@ impl PoolToNetAdapter {
}
}
/// Implements the view of the blockchain required by the TransactionPool to
/// Implements the view of the required by the TransactionPool to
/// operate. Mostly needed to break any direct lifecycle or implementation
/// dependency between the pool and the chain.
#[derive(Clone)]
@@ -732,25 +732,27 @@ impl PoolToChainAdapter {
impl pool::BlockChain for PoolToChainAdapter {
fn chain_head(&self) -> Result<BlockHeader, pool::PoolError> {
wo(&self.chain).head_header().map_err(|e| {
pool::PoolError::Other(format!(
"Chain adapter failed to retrieve chain head: {:?}",
e
))
})
wo(&self.chain)
.head_header()
.map_err(|_| pool::PoolError::Other(format!("failed to get head_header")))
}
fn validate_raw_txs(
&self,
txs: Vec<Transaction>,
pre_tx: Option<Transaction>,
block_hash: &Hash,
) -> Result<(Vec<Transaction>), pool::PoolError> {
fn get_block_header(&self, hash: &Hash) -> Result<BlockHeader, pool::PoolError> {
wo(&self.chain)
.validate_raw_txs(txs, pre_tx, block_hash)
.map_err(|e| {
pool::PoolError::Other(format!("Chain adapter failed to validate_raw_txs: {:?}", e))
})
.get_block_header(hash)
.map_err(|_| pool::PoolError::Other(format!("failed to get block_header")))
}
fn get_block_sums(&self, hash: &Hash) -> Result<BlockSums, pool::PoolError> {
wo(&self.chain)
.get_block_sums(hash)
.map_err(|_| pool::PoolError::Other(format!("failed to get block_sums")))
}
fn validate_tx(&self, tx: &Transaction, header: &BlockHeader) -> Result<(), pool::PoolError> {
wo(&self.chain)
.validate_tx(tx, header)
.map_err(|_| pool::PoolError::Other(format!("failed to validate tx")))
}
fn verify_coinbase_maturity(&self, tx: &Transaction) -> Result<(), pool::PoolError> {
+25 -17
View File
@@ -93,12 +93,15 @@ fn process_stem_phase(
let header = tx_pool.blockchain.chain_head()?;
let txpool_tx = tx_pool.txpool.aggregate_transaction()?;
let stem_txs = tx_pool.stempool.select_valid_transactions(
PoolEntryState::ToStem,
PoolEntryState::Stemmed,
txpool_tx,
&header.hash(),
)?;
let stem_txs = tx_pool
.stempool
.get_transactions_in_state(PoolEntryState::ToStem);
let stem_txs = tx_pool
.stempool
.select_valid_transactions(stem_txs, txpool_tx, &header)?;
tx_pool
.stempool
.transition_to_state(&stem_txs, PoolEntryState::Stemmed);
if stem_txs.len() > 0 {
debug!(
@@ -107,7 +110,8 @@ fn process_stem_phase(
stem_txs.len()
);
let agg_tx = transaction::aggregate(stem_txs, verifier_cache.clone())?;
let agg_tx = transaction::aggregate(stem_txs)?;
agg_tx.validate(verifier_cache.clone())?;
let res = tx_pool.adapter.stem_tx_accepted(&agg_tx);
if res.is_err() {
@@ -121,7 +125,7 @@ fn process_stem_phase(
identifier: "?.?.?.?".to_string(),
};
tx_pool.add_to_pool(src, agg_tx, false, &header.hash())?;
tx_pool.add_to_pool(src, agg_tx, false, &header)?;
}
}
Ok(())
@@ -136,12 +140,15 @@ fn process_fluff_phase(
let header = tx_pool.blockchain.chain_head()?;
let txpool_tx = tx_pool.txpool.aggregate_transaction()?;
let stem_txs = tx_pool.stempool.select_valid_transactions(
PoolEntryState::ToFluff,
PoolEntryState::Fluffed,
txpool_tx,
&header.hash(),
)?;
let stem_txs = tx_pool
.stempool
.get_transactions_in_state(PoolEntryState::ToFluff);
let stem_txs = tx_pool
.stempool
.select_valid_transactions(stem_txs, txpool_tx, &header)?;
tx_pool
.stempool
.transition_to_state(&stem_txs, PoolEntryState::Fluffed);
if stem_txs.len() > 0 {
debug!(
@@ -150,14 +157,15 @@ fn process_fluff_phase(
stem_txs.len()
);
let agg_tx = transaction::aggregate(stem_txs, verifier_cache.clone())?;
let agg_tx = transaction::aggregate(stem_txs)?;
agg_tx.validate(verifier_cache.clone())?;
let src = TxSource {
debug_name: "fluff".to_string(),
identifier: "?.?.?.?".to_string(),
};
tx_pool.add_to_pool(src, agg_tx, false, &header.hash())?;
tx_pool.add_to_pool(src, agg_tx, false, &header)?;
}
Ok(())
}
@@ -238,7 +246,7 @@ fn process_expired_entries(
debug_name: "embargo_expired".to_string(),
identifier: "?.?.?.?".to_string(),
};
match tx_pool.add_to_pool(src, entry.tx, false, &header.hash()) {
match tx_pool.add_to_pool(src, entry.tx, false, &header) {
Ok(_) => debug!(
LOGGER,
"dand_mon: embargo expired, fluffed tx successfully."
+7 -9
View File
@@ -109,7 +109,12 @@ fn build_block(
let difficulty = consensus::next_difficulty(diff_iter).unwrap();
// extract current transaction from the pool
let txs = tx_pool.read().unwrap().prepare_mineable_transactions();
// TODO - we have a lot of unwrap() going on in this fn...
let txs = tx_pool
.read()
.unwrap()
.prepare_mineable_transactions()
.unwrap();
// build the coinbase and the block itself
let fees = txs.iter().map(|tx| tx.fee()).sum();
@@ -121,14 +126,7 @@ fn build_block(
};
let (output, kernel, block_fees) = get_coinbase(wallet_listener_url, block_fees)?;
let mut b = core::Block::with_reward(
&head,
txs,
output,
kernel,
difficulty.clone(),
verifier_cache.clone(),
)?;
let mut b = core::Block::with_reward(&head, txs, output, kernel, difficulty.clone())?;
// making sure we're not spending time mining a useless block
b.validate(