Merge pull request #315 from ethcore/spendable_transactions
TransactionOutputBuilder always creates spendable transactions
This commit is contained in:
commit
5162075c6e
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
)
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue