pass in next height when applying raw txs (#1129)

rewind correctly to the previous height as necessary
This commit is contained in:
Antioch Peverell 2018-06-02 12:29:18 +01:00 committed by GitHub
parent d6b689bada
commit 0a80023527
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 15 additions and 13 deletions

View file

@ -30,8 +30,8 @@ use pipe;
use store; use store;
use txhashset; use txhashset;
use types::*; use types::*;
use util::LOGGER;
use util::secp::pedersen::{Commitment, RangeProof}; use util::secp::pedersen::{Commitment, RangeProof};
use util::LOGGER;
/// Orphan pool size is limited by MAX_ORPHAN_SIZE /// Orphan pool size is limited by MAX_ORPHAN_SIZE
pub const MAX_ORPHAN_SIZE: usize = 200; pub const MAX_ORPHAN_SIZE: usize = 200;
@ -460,25 +460,25 @@ impl Chain {
txhashset.is_unspent(output_ref) txhashset.is_unspent(output_ref)
} }
fn next_block_height(&self) -> Result<u64, Error> {
let bh = self.head_header()?;
Ok(bh.height + 1)
}
/// Validate a vector of "raw" transactions against the current chain state. /// Validate a vector of "raw" transactions against the current chain state.
pub fn validate_raw_txs( pub fn validate_raw_txs(
&self, &self,
txs: Vec<Transaction>, txs: Vec<Transaction>,
pre_tx: Option<Transaction>, pre_tx: Option<Transaction>,
) -> Result<Vec<Transaction>, Error> { ) -> Result<Vec<Transaction>, Error> {
let bh = self.head_header()?; let height = self.next_block_height()?;
let mut txhashset = self.txhashset.write().unwrap(); let mut txhashset = self.txhashset.write().unwrap();
txhashset::extending_readonly(&mut txhashset, |extension| { txhashset::extending_readonly(&mut txhashset, |extension| {
let valid_txs = extension.validate_raw_txs(txs, pre_tx, bh.height)?; let valid_txs = extension.validate_raw_txs(txs, pre_tx, height)?;
Ok(valid_txs) Ok(valid_txs)
}) })
} }
fn next_block_height(&self) -> Result<u64, Error> {
let bh = self.head_header()?;
Ok(bh.height + 1)
}
/// Verify we are not attempting to spend a coinbase output /// Verify we are not attempting to spend a coinbase output
/// that has not yet sufficiently matured. /// that has not yet sufficiently matured.
pub fn verify_coinbase_maturity(&self, tx: &Transaction) -> Result<(), Error> { pub fn verify_coinbase_maturity(&self, tx: &Transaction) -> Result<(), Error> {

View file

@ -422,25 +422,27 @@ impl<'a> Extension<'a> {
let output_pos = self.output_pmmr.unpruned_size(); let output_pos = self.output_pmmr.unpruned_size();
let kernel_pos = self.kernel_pmmr.unpruned_size(); let kernel_pos = self.kernel_pmmr.unpruned_size();
let rewind_to_height = height - 1;
// When applying blocks we can apply the coinbase output first // When applying blocks we can apply the coinbase output first
// but we cannot do this here, so we need to apply outputs first. // but we cannot do this here, so we need to apply outputs first.
for ref output in &tx.outputs { for ref output in &tx.outputs {
if let Err(e) = self.apply_output(output) { if let Err(e) = self.apply_output(output) {
self.rewind_to_pos(output_pos, kernel_pos, height)?; self.rewind_to_pos(output_pos, kernel_pos, rewind_to_height)?;
return Err(e); return Err(e);
} }
} }
for ref input in &tx.inputs { for ref input in &tx.inputs {
if let Err(e) = self.apply_input(input, height) { if let Err(e) = self.apply_input(input, height) {
self.rewind_to_pos(output_pos, kernel_pos, height)?; self.rewind_to_pos(output_pos, kernel_pos, rewind_to_height)?;
return Err(e); return Err(e);
} }
} }
for ref kernel in &tx.kernels { for ref kernel in &tx.kernels {
if let Err(e) = self.apply_kernel(kernel) { if let Err(e) = self.apply_kernel(kernel) {
self.rewind_to_pos(output_pos, kernel_pos, height)?; self.rewind_to_pos(output_pos, kernel_pos, rewind_to_height)?;
return Err(e); return Err(e);
} }
} }
@ -474,13 +476,13 @@ impl<'a> Extension<'a> {
let mut height = height; let mut height = height;
let mut valid_txs = vec![]; let mut valid_txs = vec![];
if let Some(tx) = pre_tx { if let Some(tx) = pre_tx {
height += 1;
self.apply_raw_tx(&tx, height)?; self.apply_raw_tx(&tx, height)?;
height += 1;
} }
for tx in txs { for tx in txs {
height += 1;
if self.apply_raw_tx(&tx, height).is_ok() { if self.apply_raw_tx(&tx, height).is_ok() {
valid_txs.push(tx); valid_txs.push(tx);
height += 1;
} }
} }
Ok(valid_txs) Ok(valid_txs)