Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Input and output previous STXO block validation check #1974

Merged
merged 1 commit into from
Jun 11, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion base_layer/core/src/chain_storage/lmdb_db/lmdb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ use lmdb_zero::{
CursorIter,
Database,
Environment,
Ignore,
MaybeOwned,
ReadTransaction,
WriteTransaction,
Expand Down
30 changes: 28 additions & 2 deletions base_layer/core/src/validation/block_validators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
BlockValidationError,
NewBlockTemplate,
},
chain_storage::{calculate_mmr_roots, is_utxo, BlockchainBackend},
chain_storage::{calculate_mmr_roots, is_stxo, is_utxo, BlockchainBackend},
consensus::{ConsensusConstants, ConsensusManager},
transactions::{transaction::OutputFlags, types::CryptoFactories},
validation::{
Expand Down Expand Up @@ -108,6 +108,7 @@ impl<B: BlockchainBackend> Validation<Block, B> for FullConsensusValidator {
/// The consensus checks that are done (in order of cheapest to verify to most expensive):
/// 1. Does the block satisfy the stateless checks?
/// 1. Are all inputs currently in the UTXO set?
/// 1. Are all inputs and outputs not in the STXO set?
/// 1. Are the block header MMR roots valid?
/// 1. Is the block header timestamp less than the ftl?
/// 1. Is the block header timestamp greater than the median timestamp?
Expand All @@ -116,9 +117,10 @@ impl<B: BlockchainBackend> Validation<Block, B> for FullConsensusValidator {
fn validate(&self, block: &Block, db: &B) -> Result<(), ValidationError> {
let block_id = format!("block #{} ({})", block.header.height, block.hash().to_hex());
check_inputs_are_utxos(block, db)?;
check_not_stxos(block, db)?;
trace!(
target: LOG_TARGET,
"Block validation: All inputs are valid for {}",
"Block validation: All inputs and outputs are valid for {}",
&block_id
);
check_mmr_roots(block, db)?;
Expand Down Expand Up @@ -272,6 +274,30 @@ fn check_inputs_are_utxos<B: BlockchainBackend>(block: &Block, db: &B) -> Result
Ok(())
}

// This function checks that the inputs and outputs do not exist in the STxO set.
fn check_not_stxos<B: BlockchainBackend>(block: &Block, db: &B) -> Result<(), ValidationError> {
for input in block.body.inputs() {
if is_stxo(db, input.hash()).map_err(|e| ValidationError::CustomError(e.to_string()))? {
// we dont want to log this as a node or wallet might retransmit a transaction
debug!(
target: LOG_TARGET,
"Block validation failed due to already spent input: {}", input
);
return Err(ValidationError::ContainsSTxO);
}
}
for output in block.body.outputs() {
if is_stxo(db, output.hash()).map_err(|e| ValidationError::CustomError(e.to_string()))? {
debug!(
target: LOG_TARGET,
"Block validation failed due to previously spent output: {}", output
);
return Err(ValidationError::ContainsSTxO);
}
}
Ok(())
}

/// This function tests that the block timestamp is less than the ftl.
fn check_timestamp_ftl(
block_header: &BlockHeader,
Expand Down