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(), &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
use super::genesis;
use chain;
use std::cell::Cell;
use primitives::hash::H256;
use primitives::bytes::Bytes;
use primitives::compact::Compact;
use chain;
use invoke::{Invoke, Identity};
use std::cell::Cell;
use super::genesis;
thread_local! {
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> {
callback: F,
value: u64,
signature: Bytes,
script_pubkey: Bytes,
}
impl<F> TransactionOutputBuilder<F> where F: Invoke<chain::TransactionOutput> {
fn with_callback(callback: F) -> Self {
TransactionOutputBuilder {
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,
}
}
@ -394,20 +396,20 @@ impl<F> TransactionOutputBuilder<F> where F: Invoke<chain::TransactionOutput> {
self
}
pub fn signature(mut self, sig: &'static str) -> Self {
self.signature = sig.into();
pub fn script_pubkey(mut self, script_pubkey: &'static str) -> Self {
self.script_pubkey = script_pubkey.into();
self
}
pub fn signature_bytes(mut self, sig: Bytes) -> Self {
self.signature = sig;
pub fn script_pubkey_bytes(mut self, script_pubkey: Bytes) -> Self {
self.script_pubkey = script_pubkey;
self
}
pub fn build(self) -> F::Result {
self.callback.invoke(
chain::TransactionOutput {
script_pubkey: self.signature,
script_pubkey: self.script_pubkey,
value: self.value,
}
)

View File

@ -40,23 +40,14 @@ impl<'a> ChainAcceptor<'a> {
pub fn check(&self) -> Result<(), Error> {
try!(self.block.check());
try!(self.header.check());
try!(self.check_transactions_with_eval(true));
try!(self.check_transactions());
Ok(())
}
/// backwards test compatibility
/// 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> {
fn check_transactions(&self) -> Result<(), Error> {
self.transactions.par_iter()
.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))
}
}

View File

@ -53,20 +53,6 @@ impl<'a> TransactionAcceptor<'a> {
try!(self.eval.check());
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> {

View File

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