[WIP] txpool (tx validation) using block sums for full validation (#1567)
tx validation (txpool) rework/simplify
This commit is contained in:
@@ -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> {
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user