Do not wrap transactions into Box in pool (#1069)

It makes code more complex and may require more memory allocations than needed.
This commit is contained in:
hashmap 2018-05-16 01:21:33 +02:00 committed by Ignotus Peverell
parent 54b06a6fcb
commit 3026429b05
4 changed files with 56 additions and 53 deletions

View file

@ -14,11 +14,11 @@
//! Top-level Pool type, methods, and tests //! Top-level Pool type, methods, and tests
use rand;
use rand::Rng;
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::sync::Arc; use std::sync::Arc;
use time; use time;
use rand;
use rand::Rng;
use core::core::hash::Hash; use core::core::hash::Hash;
use core::core::hash::Hashed; use core::core::hash::Hashed;
@ -29,8 +29,8 @@ use core::core::{block, hash};
use util::LOGGER; use util::LOGGER;
use util::secp::pedersen::Commitment; use util::secp::pedersen::Commitment;
use types::*;
pub use graph; pub use graph;
use types::*;
/// The pool itself. /// The pool itself.
/// The transactions HashMap holds ownership of all transactions in the pool, /// The transactions HashMap holds ownership of all transactions in the pool,
@ -42,9 +42,9 @@ pub struct TransactionPool<T> {
/// propagation /// propagation
pub time_stem_transactions: HashMap<hash::Hash, i64>, pub time_stem_transactions: HashMap<hash::Hash, i64>,
/// All transactions in the stempool /// All transactions in the stempool
pub stem_transactions: HashMap<hash::Hash, Box<transaction::Transaction>>, pub stem_transactions: HashMap<hash::Hash, transaction::Transaction>,
/// All transactions in the pool /// All transactions in the pool
pub transactions: HashMap<hash::Hash, Box<transaction::Transaction>>, pub transactions: HashMap<hash::Hash, transaction::Transaction>,
/// The stem pool /// The stem pool
pub stempool: Pool, pub stempool: Pool,
/// The pool itself /// The pool itself
@ -99,7 +99,7 @@ where
// if any kernel matches then keep the tx for later // if any kernel matches then keep the tx for later
if cb.kern_ids.contains(&short_id) { if cb.kern_ids.contains(&short_id) {
txs.push(*tx.clone()); txs.push(tx.clone());
break; break;
} }
} }
@ -208,10 +208,10 @@ where
/// Attempts to add a transaction to the stempool or the memory pool. /// Attempts to add a transaction to the stempool or the memory pool.
/// ///
/// Adds a transaction to the stem memory pool, deferring to the orphans pool /// Adds a transaction to the stem memory pool, deferring to the orphans
/// if necessary, and performing any connection-related validity checks. /// pool if necessary, and performing any connection-related validity
/// Happens under an exclusive mutable reference gated by the write portion /// checks. Happens under an exclusive mutable reference gated by the
/// of a RWLock. /// write portion of a RWLock.
pub fn add_to_memory_pool( pub fn add_to_memory_pool(
&mut self, &mut self,
_: TxSource, _: TxSource,
@ -349,7 +349,7 @@ where
); );
self.adapter.stem_tx_accepted(&tx); self.adapter.stem_tx_accepted(&tx);
self.stem_transactions.insert(tx_hash, Box::new(tx)); self.stem_transactions.insert(tx_hash, tx);
// Track this transaction // Track this transaction
self.time_stem_transactions.insert(tx_hash, timer); self.time_stem_transactions.insert(tx_hash, timer);
} else { } else {
@ -361,7 +361,7 @@ where
new_unspents, new_unspents,
); );
self.adapter.tx_accepted(&tx); self.adapter.tx_accepted(&tx);
self.transactions.insert(tx_hash, Box::new(tx)); self.transactions.insert(tx_hash, tx);
} }
self.reconcile_orphans().unwrap(); self.reconcile_orphans().unwrap();
Ok(()) Ok(())
@ -429,8 +429,8 @@ where
} }
} }
/// Attempt to deaggregate multi-kernel transaction as much as possible based on the content /// Attempt to deaggregate multi-kernel transaction as much as possible
/// of the mempool /// based on the content of the mempool
pub fn deaggregate_transaction( pub fn deaggregate_transaction(
&self, &self,
tx: transaction::Transaction, tx: transaction::Transaction,
@ -477,7 +477,7 @@ where
&& candidates_kernels_set.is_subset(&kernels_set) && candidates_kernels_set.is_subset(&kernels_set)
{ {
debug!(LOGGER, "Found a transaction with the same kernel"); debug!(LOGGER, "Found a transaction with the same kernel");
found_txs.push(*tx.clone()); found_txs.push(tx.clone());
} }
} }
@ -636,7 +636,7 @@ where
pub fn reconcile_block( pub fn reconcile_block(
&mut self, &mut self,
block: &block::Block, block: &block::Block,
) -> Result<Vec<Box<transaction::Transaction>>, PoolError> { ) -> Result<Vec<transaction::Transaction>, PoolError> {
// If this pool has been kept in sync correctly, serializing all // If this pool has been kept in sync correctly, serializing all
// updates, then the inputs must consume only members of the blockchain // updates, then the inputs must consume only members of the blockchain
// output set. // output set.
@ -796,7 +796,7 @@ where
&mut self, &mut self,
marked_transactions: HashSet<hash::Hash>, marked_transactions: HashSet<hash::Hash>,
stem: bool, stem: bool,
) -> Vec<Box<transaction::Transaction>> { ) -> Vec<transaction::Transaction> {
let mut removed_txs = Vec::new(); let mut removed_txs = Vec::new();
if stem { if stem {
@ -839,7 +839,7 @@ where
pub fn prepare_mineable_transactions( pub fn prepare_mineable_transactions(
&self, &self,
num_to_fetch: u32, num_to_fetch: u32,
) -> Vec<Box<transaction::Transaction>> { ) -> Vec<transaction::Transaction> {
self.pool self.pool
.get_mineable_transactions(num_to_fetch) .get_mineable_transactions(num_to_fetch)
.iter() .iter()

View file

@ -26,19 +26,19 @@ extern crate time;
use std::collections::HashMap; use std::collections::HashMap;
use core::core::block;
use core::core::transaction::{self, ProofMessageElements}; use core::core::transaction::{self, ProofMessageElements};
use core::core::{OutputIdentifier, Transaction}; use core::core::{OutputIdentifier, Transaction};
use core::core::block;
use pool::*;
use core::global;
use blockchain::{DummyChain, DummyChainImpl, DummyOutputSet}; use blockchain::{DummyChain, DummyChainImpl, DummyOutputSet};
use std::sync::{Arc, RwLock};
use core::global::ChainTypes;
use core::core::Proof; use core::core::Proof;
use core::core::hash::{Hash, Hashed}; use core::core::hash::{Hash, Hashed};
use core::core::pmmr::MerkleProof; use core::core::pmmr::MerkleProof;
use core::core::target::Difficulty; use core::core::target::Difficulty;
use core::global;
use core::global::ChainTypes;
use pool::*;
use std::sync::{Arc, RwLock};
use types::PoolError::InvalidTx; use types::PoolError::InvalidTx;
use keychain::Keychain; use keychain::Keychain;
@ -182,8 +182,9 @@ fn test_multikernel_pool_add() {
#[test] #[test]
/// Attempt to deaggregate a multi_kernel transaction /// Attempt to deaggregate a multi_kernel transaction
/// Push the parent transaction in the mempool then send a multikernel tx containing it and a /// Push the parent transaction in the mempool then send a multikernel tx
/// child transaction In the end, the pool should contain both transactions. /// containing it and a child transaction In the end, the pool should contain
/// both transactions.
fn test_multikernel_deaggregate() { fn test_multikernel_deaggregate() {
let mut dummy_chain = DummyChainImpl::new(); let mut dummy_chain = DummyChainImpl::new();
let head_header = block::BlockHeader { let head_header = block::BlockHeader {
@ -366,8 +367,8 @@ fn test_pool_stempool_add() {
} }
#[test] #[test]
/// A basic test; add a transaction to the stempool and one the regular transaction pool /// A basic test; add a transaction to the stempool and one the regular
/// Child transaction should be added to the stempool. /// transaction pool Child transaction should be added to the stempool.
fn test_stempool_pool_add() { fn test_stempool_pool_add() {
let mut dummy_chain = DummyChainImpl::new(); let mut dummy_chain = DummyChainImpl::new();
let head_header = block::BlockHeader { let head_header = block::BlockHeader {
@ -645,7 +646,7 @@ fn test_zero_confirmation_reconciliation() {
{ {
let read_pool = pool.read().unwrap(); let read_pool = pool.read().unwrap();
let mut mineable_txs = read_pool.prepare_mineable_transactions(3); let mut mineable_txs = read_pool.prepare_mineable_transactions(3);
txs = mineable_txs.drain(..).map(|x| *x).collect(); txs = mineable_txs.drain(..).collect();
// confirm we can preparing both txs for mining here // confirm we can preparing both txs for mining here
// one root tx in the pool, and one non-root vertex in the pool // one root tx in the pool, and one non-root vertex in the pool
@ -908,7 +909,7 @@ fn test_block_building() {
// Request blocks // Request blocks
let block: block::Block; let block: block::Block;
let mut txs: Vec<Box<transaction::Transaction>>; let mut txs: Vec<transaction::Transaction>;
{ {
let read_pool = pool.read().unwrap(); let read_pool = pool.read().unwrap();
txs = read_pool.prepare_mineable_transactions(3); txs = read_pool.prepare_mineable_transactions(3);
@ -916,7 +917,7 @@ fn test_block_building() {
// TODO: This is ugly, either make block::new take owned // TODO: This is ugly, either make block::new take owned
// txs instead of mut refs, or change // txs instead of mut refs, or change
// prepare_mineable_transactions to return mut refs // prepare_mineable_transactions to return mut refs
let block_txs: Vec<transaction::Transaction> = txs.drain(..).map(|x| *x).collect(); let block_txs: Vec<transaction::Transaction> = txs.drain(..).collect();
let tx_refs: Vec<&transaction::Transaction> = block_txs.iter().collect(); let tx_refs: Vec<&transaction::Transaction> = block_txs.iter().collect();
let keychain = Keychain::from_random_seed().unwrap(); let keychain = Keychain::from_random_seed().unwrap();

View file

@ -12,24 +12,25 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, RwLock};
use std::thread; use std::thread;
use std::time::Duration; use std::time::Duration;
use std::sync::{Arc, RwLock};
use std::sync::atomic::{AtomicBool, Ordering};
use time::now_utc; use time::now_utc;
use util::LOGGER; use util::LOGGER;
use pool::TransactionPool;
use pool::PoolConfig;
use pool::TxSource;
use pool::BlockChain; use pool::BlockChain;
use pool::PoolConfig;
use pool::TransactionPool;
use pool::TxSource;
/// A process to monitor transactions in the stempool. /// A process to monitor transactions in the stempool.
/// With Dandelion, transaction can be broadcasted in stem or fluff phase. /// With Dandelion, transaction can be broadcasted in stem or fluff phase.
/// When sent in stem phase, the transaction is relayed to only node: the dandelion relay. In /// When sent in stem phase, the transaction is relayed to only node: the
/// order to maintain reliability a timer is started for each transaction sent in stem phase. /// dandelion relay. In order to maintain reliability a timer is started for
/// This function will monitor the stempool and test if the timer is expired for each transaction. /// each transaction sent in stem phase. This function will monitor the
/// In that case the transaction will be sent in fluff phase (to multiple peers) instead of /// stempool and test if the timer is expired for each transaction. In that case
/// the transaction will be sent in fluff phase (to multiple peers) instead of
/// sending only to the peer relay. /// sending only to the peer relay.
pub fn monitor_transactions<T>( pub fn monitor_transactions<T>(
config: PoolConfig, config: PoolConfig,
@ -59,7 +60,7 @@ pub fn monitor_transactions<T>(
let stem_transaction = stem_transactions.get(tx_hash).unwrap(); let stem_transaction = stem_transactions.get(tx_hash).unwrap();
let res = tx_pool.write().unwrap().add_to_memory_pool( let res = tx_pool.write().unwrap().add_to_memory_pool(
source, source,
*stem_transaction.clone(), stem_transaction.clone(),
false, false,
); );

View file

@ -15,29 +15,29 @@
//! Build a block to mine: gathers transactions from the pool, assembles //! Build a block to mine: gathers transactions from the pool, assembles
//! them into a block and returns it. //! them into a block and returns it.
use std::thread;
use std::sync::{Arc, RwLock};
use time;
use std::time::Duration;
use rand::{self, Rng};
use itertools::Itertools; use itertools::Itertools;
use rand::{self, Rng};
use std::sync::{Arc, RwLock};
use std::thread;
use std::time::Duration;
use time;
use core::ser::AsFixedBytes;
use chain; use chain;
use chain::types::BlockSums; use chain::types::BlockSums;
use pool; use common::adapters::PoolToChainAdapter;
use common::types::Error;
use core::consensus; use core::consensus;
use core::core; use core::core;
use core::core::Transaction; use core::core::Transaction;
use core::core::hash::Hashed; use core::core::hash::Hashed;
use core::ser; use core::ser;
use core::ser::AsFixedBytes;
use keychain::{Identifier, Keychain}; use keychain::{Identifier, Keychain};
use wallet; use pool;
use wallet::BlockFees;
use util; use util;
use util::LOGGER; use util::LOGGER;
use common::types::Error; use wallet;
use common::adapters::PoolToChainAdapter; use wallet::BlockFees;
/// Serializer that outputs the pre-pow part of the header, /// Serializer that outputs the pre-pow part of the header,
/// including the nonce (last 8 bytes) that can be sent off /// including the nonce (last 8 bytes) that can be sent off
@ -158,11 +158,12 @@ fn build_block(
let difficulty = consensus::next_difficulty(diff_iter).unwrap(); let difficulty = consensus::next_difficulty(diff_iter).unwrap();
// extract current transaction from the pool // extract current transaction from the pool
let txs_box = tx_pool let txs = tx_pool
.read() .read()
.unwrap() .unwrap()
.prepare_mineable_transactions(max_tx); .prepare_mineable_transactions(max_tx);
let txs: Vec<&Transaction> = txs_box.iter().map(|tx| tx.as_ref()).collect();
let txs: Vec<&Transaction> = txs.iter().collect();
// build the coinbase and the block itself // build the coinbase and the block itself
let fees = txs.iter().map(|tx| tx.fee()).sum(); let fees = txs.iter().map(|tx| tx.fee()).sum();