finished block assembler
This commit is contained in:
parent
3080ade4bd
commit
3ca513d88f
|
@ -1,6 +1,7 @@
|
|||
use std::cmp;
|
||||
use primitives::hash::H256;
|
||||
use chain::Transaction;
|
||||
use chain::{Transaction, OutPoint, TransactionOutput};
|
||||
use PreviousTransactionOutputProvider;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct IndexedTransaction {
|
||||
|
@ -23,3 +24,15 @@ impl cmp::PartialEq for IndexedTransaction {
|
|||
self.hash == other.hash
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> PreviousTransactionOutputProvider for &'a [IndexedTransaction] {
|
||||
fn previous_transaction_output(&self, prevout: &OutPoint) -> Option<TransactionOutput> {
|
||||
self.iter()
|
||||
.find(|tx| tx.hash == prevout.hash)
|
||||
.map(|tx| tx.transaction.outputs[prevout.index as usize].clone())
|
||||
}
|
||||
|
||||
fn is_spent(&self, _prevout: &OutPoint) -> bool {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ use primitives::hash::H256;
|
|||
use db::{SharedStore, IndexedTransaction};
|
||||
use network::Magic;
|
||||
use memory_pool::{MemoryPool, OrderingStrategy};
|
||||
use verification::{work_required, block_reward_satoshi};
|
||||
use verification::{work_required, block_reward_satoshi, transaction_sigops, StoreWithUnretainedOutputs};
|
||||
|
||||
const BLOCK_VERSION: u32 = 0x20000000;
|
||||
const MAX_BLOCK_SIZE: u32 = 1_000_000;
|
||||
|
@ -145,9 +145,9 @@ impl BlockAssembler {
|
|||
|
||||
let mut transactions = Vec::new();
|
||||
// add priority transactions
|
||||
BlockAssembler::fill_transactions(mempool, &mut block_size, &mut sigops, &mut coinbase_value, &mut transactions, OrderingStrategy::ByTransactionScore);
|
||||
BlockAssembler::fill_transactions(store, mempool, &mut block_size, &mut sigops, &mut coinbase_value, &mut transactions, OrderingStrategy::ByTransactionScore);
|
||||
// add package transactions
|
||||
BlockAssembler::fill_transactions(mempool, &mut block_size, &mut sigops, &mut coinbase_value, &mut transactions, OrderingStrategy::ByPackageScore);
|
||||
BlockAssembler::fill_transactions(store, mempool, &mut block_size, &mut sigops, &mut coinbase_value, &mut transactions, OrderingStrategy::ByPackageScore);
|
||||
|
||||
BlockTemplate {
|
||||
version: version,
|
||||
|
@ -163,6 +163,7 @@ impl BlockAssembler {
|
|||
}
|
||||
|
||||
fn fill_transactions(
|
||||
store: &SharedStore,
|
||||
mempool: &MemoryPool,
|
||||
block_size: &mut SizePolicy,
|
||||
sigops: &mut SizePolicy,
|
||||
|
@ -175,12 +176,16 @@ impl BlockAssembler {
|
|||
break;
|
||||
}
|
||||
|
||||
// TODO: calucalte sigops
|
||||
let transaction_size = entry.size as u32;
|
||||
let transaction_sigops = 0;
|
||||
let sigops_count = {
|
||||
let txs: &[_] = &*transactions;
|
||||
let unretained_store = StoreWithUnretainedOutputs::new(store, &txs);
|
||||
let bip16_active = true;
|
||||
transaction_sigops(&entry.transaction, &unretained_store, bip16_active) as u32
|
||||
};
|
||||
|
||||
let size_step = block_size.decide(transaction_size);
|
||||
let sigops_step = sigops.decide(transaction_sigops);
|
||||
let sigops_step = sigops.decide(sigops_count);
|
||||
|
||||
let transaction = IndexedTransaction {
|
||||
transaction: entry.transaction.clone(),
|
||||
|
|
|
@ -77,7 +77,7 @@ impl ChainVerifier {
|
|||
fn block_sigops(&self, block: &db::IndexedBlock) -> usize {
|
||||
// strict pay-to-script-hash signature operations count toward block
|
||||
// signature operations limit is enforced with BIP16
|
||||
let store = StoreWithUnretainedOutputs::new(self.store.clone(), block);
|
||||
let store = StoreWithUnretainedOutputs::new(&self.store, block);
|
||||
let bip16_active = self.verify_p2sh(block.header().time);
|
||||
block.transactions().map(|(_, tx)| transaction_sigops(tx, &store, bip16_active)).sum()
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ impl ChainVerifier {
|
|||
}
|
||||
}
|
||||
|
||||
let unretained_store = StoreWithUnretainedOutputs::new(self.store.clone(), block);
|
||||
let unretained_store = StoreWithUnretainedOutputs::new(&self.store, block);
|
||||
let mut total_unspent = 0u64;
|
||||
for (tx_index, (_, tx)) in block.transactions().enumerate().skip(1) {
|
||||
let mut total_claimed: u64 = 0;
|
||||
|
@ -189,7 +189,7 @@ impl ChainVerifier {
|
|||
// must not be coinbase (sequence = 0 is returned above)
|
||||
if transaction.is_coinbase() { return Err(TransactionError::MisplacedCoinbase(sequence)); }
|
||||
|
||||
let unretained_store = StoreWithUnretainedOutputs::new(self.store.clone(), prevout_provider);
|
||||
let unretained_store = StoreWithUnretainedOutputs::new(&self.store, prevout_provider);
|
||||
for (input_index, input) in transaction.inputs().iter().enumerate() {
|
||||
// signature verification
|
||||
let signer: TransactionInputSigner = transaction.clone().into();
|
||||
|
|
|
@ -3,12 +3,12 @@ use db::{PreviousTransactionOutputProvider, SharedStore};
|
|||
use script::Script;
|
||||
|
||||
pub struct StoreWithUnretainedOutputs<'a, T> where T: 'a {
|
||||
store: SharedStore,
|
||||
store: &'a SharedStore,
|
||||
outputs: &'a T,
|
||||
}
|
||||
|
||||
impl<'a, T> StoreWithUnretainedOutputs<'a, T> where T: PreviousTransactionOutputProvider {
|
||||
pub fn new(store: SharedStore, outputs: &'a T) -> Self {
|
||||
pub fn new(store: &'a SharedStore, outputs: &'a T) -> Self {
|
||||
StoreWithUnretainedOutputs {
|
||||
store: store,
|
||||
outputs: outputs,
|
||||
|
|
Loading…
Reference in New Issue