TransactionOutputGenerator always creates spendable transactions

This commit is contained in:
debris 2016-12-13 12:41:27 +01:00
parent 80f17977c1
commit 8d7a45f2ca
5 changed files with 24 additions and 53 deletions

View File

@ -54,6 +54,6 @@ mod tests {
assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx0), 0); assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx0), 0);
assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx1), 0); assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx1), 0);
assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx2), 4_950); assert_eq!(transaction_fee_rate(db.as_transaction_provider(), &tx2), 4_901);
} }
} }

View File

@ -1,12 +1,12 @@
//! Block builder //! Block builder
use super::genesis; use std::cell::Cell;
use chain;
use primitives::hash::H256; use primitives::hash::H256;
use primitives::bytes::Bytes; use primitives::bytes::Bytes;
use primitives::compact::Compact; use primitives::compact::Compact;
use chain;
use invoke::{Invoke, Identity}; use invoke::{Invoke, Identity};
use std::cell::Cell; use super::genesis;
thread_local! { thread_local! {
pub static TIMESTAMP_COUNTER: Cell<u32> = Cell::new(0); pub static TIMESTAMP_COUNTER: Cell<u32> = Cell::new(0);
@ -377,14 +377,16 @@ impl<F> TransactionInputBuilder<F> where F: Invoke<chain::TransactionInput> {
pub struct TransactionOutputBuilder<F=Identity> { pub struct TransactionOutputBuilder<F=Identity> {
callback: F, callback: F,
value: u64, value: u64,
signature: Bytes, script_pubkey: Bytes,
} }
impl<F> TransactionOutputBuilder<F> where F: Invoke<chain::TransactionOutput> { impl<F> TransactionOutputBuilder<F> where F: Invoke<chain::TransactionOutput> {
fn with_callback(callback: F) -> Self { fn with_callback(callback: F) -> Self {
TransactionOutputBuilder { TransactionOutputBuilder {
callback: callback, callback: callback,
signature: Bytes::new_with_len(0), // 0x51 is OP_1 opcode
// so the evaluation is always true
script_pubkey: vec![0x51].into(),
value: 0, value: 0,
} }
} }
@ -394,20 +396,20 @@ impl<F> TransactionOutputBuilder<F> where F: Invoke<chain::TransactionOutput> {
self self
} }
pub fn signature(mut self, sig: &'static str) -> Self { pub fn script_pubkey(mut self, script_pubkey: &'static str) -> Self {
self.signature = sig.into(); self.script_pubkey = script_pubkey.into();
self self
} }
pub fn signature_bytes(mut self, sig: Bytes) -> Self { pub fn script_pubkey_bytes(mut self, script_pubkey: Bytes) -> Self {
self.signature = sig; self.script_pubkey = script_pubkey;
self self
} }
pub fn build(self) -> F::Result { pub fn build(self) -> F::Result {
self.callback.invoke( self.callback.invoke(
chain::TransactionOutput { chain::TransactionOutput {
script_pubkey: self.signature, script_pubkey: self.script_pubkey,
value: self.value, value: self.value,
} }
) )

View File

@ -40,23 +40,14 @@ impl<'a> ChainAcceptor<'a> {
pub fn check(&self) -> Result<(), Error> { pub fn check(&self) -> Result<(), Error> {
try!(self.block.check()); try!(self.block.check());
try!(self.header.check()); try!(self.header.check());
try!(self.check_transactions_with_eval(true)); try!(self.check_transactions());
Ok(()) Ok(())
} }
/// backwards test compatibility fn check_transactions(&self) -> Result<(), Error> {
/// TODO: get rid of this
pub fn check_with_eval(&self, eval: bool) -> Result<(), Error> {
try!(self.block.check());
try!(self.header.check());
try!(self.check_transactions_with_eval(eval));
Ok(())
}
fn check_transactions_with_eval(&self, eval: bool) -> Result<(), Error> {
self.transactions.par_iter() self.transactions.par_iter()
.enumerate() .enumerate()
.fold(|| Ok(()), |result, (index, tx)| result.and_then(|_| tx.check_with_eval(eval).map_err(|err| Error::Transaction(index, err)))) .fold(|| Ok(()), |result, (index, tx)| result.and_then(|_| tx.check().map_err(|err| Error::Transaction(index, err))))
.reduce(|| Ok(()), |acc, check| acc.and(check)) .reduce(|| Ok(()), |acc, check| acc.and(check))
} }
} }

View File

@ -53,20 +53,6 @@ impl<'a> TransactionAcceptor<'a> {
try!(self.eval.check()); try!(self.eval.check());
Ok(()) Ok(())
} }
/// backwards test compatibility
/// TODO: get rid of this
pub fn check_with_eval(&self, eval: bool) -> Result<(), TransactionError> {
try!(self.bip30.check());
try!(self.missing_inputs.check());
try!(self.maturity.check());
try!(self.overspent.check());
try!(self.double_spent.check());
if eval {
try!(self.eval.check());
}
Ok(())
}
} }
pub struct MemoryPoolTransactionAcceptor<'a> { pub struct MemoryPoolTransactionAcceptor<'a> {

View File

@ -30,7 +30,6 @@ pub type VerificationResult = Result<Chain, Error>;
pub struct BackwardsCompatibleChainVerifier { pub struct BackwardsCompatibleChainVerifier {
store: db::SharedStore, store: db::SharedStore,
skip_pow: bool, skip_pow: bool,
skip_sig: bool,
network: Magic, network: Magic,
} }
@ -39,7 +38,6 @@ impl BackwardsCompatibleChainVerifier {
BackwardsCompatibleChainVerifier { BackwardsCompatibleChainVerifier {
store: store, store: store,
skip_pow: false, skip_pow: false,
skip_sig: false,
network: network, network: network,
} }
} }
@ -50,12 +48,6 @@ impl BackwardsCompatibleChainVerifier {
self self
} }
#[cfg(test)]
pub fn signatures_skip(mut self) -> Self {
self.skip_sig = true;
self
}
fn verify_block(&self, block: &db::IndexedBlock) -> VerificationResult { fn verify_block(&self, block: &db::IndexedBlock) -> VerificationResult {
let current_time = ::time::get_time().sec as u32; let current_time = ::time::get_time().sec as u32;
// first run pre-verification // first run pre-verification
@ -73,7 +65,7 @@ impl BackwardsCompatibleChainVerifier {
// now do full verification // now do full verification
let canon_block = CanonBlock::new(block); let canon_block = CanonBlock::new(block);
let chain_acceptor = ChainAcceptor::new(&self.store, self.network, canon_block, location.height()); let chain_acceptor = ChainAcceptor::new(&self.store, self.network, canon_block, location.height());
try!(chain_acceptor.check_with_eval(!self.skip_sig)); try!(chain_acceptor.check());
match location { match location {
BlockLocation::Main(_) => Ok(Chain::Main), BlockLocation::Main(_) => Ok(Chain::Main),
@ -206,7 +198,7 @@ mod tests {
.merkled_header().parent(genesis.hash()).build() .merkled_header().parent(genesis.hash()).build()
.build(); .build();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Err(Error::Transaction( let expected = Err(Error::Transaction(
1, 1,
@ -247,7 +239,7 @@ mod tests {
.merkled_header().parent(genesis.hash()).build() .merkled_header().parent(genesis.hash()).build()
.build(); .build();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Ok(Chain::Main); let expected = Ok(Chain::Main);
assert_eq!(expected, verifier.verify(&block.into())); assert_eq!(expected, verifier.verify(&block.into()));
@ -289,7 +281,7 @@ mod tests {
.merkled_header().parent(genesis.hash()).build() .merkled_header().parent(genesis.hash()).build()
.build(); .build();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Ok(Chain::Main); let expected = Ok(Chain::Main);
assert_eq!(expected, verifier.verify(&block.into())); assert_eq!(expected, verifier.verify(&block.into()));
@ -333,7 +325,7 @@ mod tests {
.merkled_header().parent(genesis.hash()).build() .merkled_header().parent(genesis.hash()).build()
.build(); .build();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Err(Error::Transaction(2, TransactionError::Overspend)); let expected = Err(Error::Transaction(2, TransactionError::Overspend));
assert_eq!(expected, verifier.verify(&block.into())); assert_eq!(expected, verifier.verify(&block.into()));
@ -377,7 +369,7 @@ mod tests {
.merkled_header().parent(best_hash).build() .merkled_header().parent(best_hash).build()
.build(); .build();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Ok(Chain::Main); let expected = Ok(Chain::Main);
@ -430,7 +422,7 @@ mod tests {
.build() .build()
.into(); .into();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Err(Error::MaximumSigops); let expected = Err(Error::MaximumSigops);
assert_eq!(expected, verifier.verify(&block.into())); assert_eq!(expected, verifier.verify(&block.into()));
@ -457,7 +449,7 @@ mod tests {
.build() .build()
.into(); .into();
let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip().signatures_skip(); let verifier = ChainVerifier::new(Arc::new(storage), Magic::Testnet).pow_skip();
let expected = Err(Error::CoinbaseOverspend { let expected = Err(Error::CoinbaseOverspend {
expected_max: 5000000000, expected_max: 5000000000,