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

feat: add validation for zero confirmation block sync #6237

Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -110,27 +110,44 @@ fn validate_input_not_pruned<B: BlockchainBackend>(
db: &B,
) -> Result<Vec<TransactionInput>, ValidationError> {
let mut inputs: Vec<TransactionInput> = body.inputs().clone();
let outputs: Vec<TransactionOutput> = body.outputs().clone();
for input in &mut inputs {
if input.is_compact() {
let output_mined_info = db
.fetch_output(&input.output_hash())?
.ok_or(ValidationError::UnknownInput)?;
let output = match db.fetch_output(&input.output_hash()) {
Ok(val) => match val {
Some(output_mined_info) => output_mined_info.output,
None => {
let input_output_hash = input.output_hash();
if let Some(found) = outputs.iter().find(|o| o.hash() == input_output_hash) {
found.clone()
} else {
warn!(
target: LOG_TARGET,
"Input not found in database or block, commitment: {}, hash: {}",
input.commitment()?.to_hex(), input_output_hash.to_hex()
);
return Err(ValidationError::UnknownInput);
}
},
},
Err(e) => return Err(ValidationError::from(e)),
};

let rp_hash = match output_mined_info.output.proof {
let rp_hash = match output.proof {
Some(proof) => proof.hash(),
None => FixedHash::zero(),
};
input.add_output_data(
output_mined_info.output.version,
output_mined_info.output.features,
output_mined_info.output.commitment,
output_mined_info.output.script,
output_mined_info.output.sender_offset_public_key,
output_mined_info.output.covenant,
output_mined_info.output.encrypted_data,
output_mined_info.output.metadata_signature,
output.version,
output.features,
output.commitment,
output.script,
output.sender_offset_public_key,
output.covenant,
output.encrypted_data,
output.metadata_signature,
rp_hash,
output_mined_info.output.minimum_value_promise,
output.minimum_value_promise,
);
}
}
Expand Down Expand Up @@ -207,11 +224,16 @@ fn check_inputs_are_utxos<B: BlockchainBackend>(db: &B, body: &AggregateBody) ->
}

let output_hashes = output_hashes.as_ref().unwrap();
let output_hash = input.output_hash();
if output_hashes.iter().any(|output| output == &output_hash) {
let input_output_hash = input.output_hash();
if output_hashes.iter().any(|val| val == &input_output_hash) {
continue;
}
not_found_inputs.push(output_hash);
warn!(
target: LOG_TARGET,
"Input not found in database, commitment: {}, hash: {}",
input.commitment()?.to_hex(), input_output_hash.to_hex()
);
not_found_inputs.push(input_output_hash);
},
Err(err) => {
return Err(err);
Expand Down
5 changes: 3 additions & 2 deletions base_layer/core/src/validation/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ pub fn is_all_unique_and_sorted<'a, I: IntoIterator<Item = &'a T>, T: PartialOrd
true
}

/// This function checks that an input is a valid spendable UTXO
/// This function checks that an input is a valid spendable UTXO in the database. It cannot confirm
/// zero confermation transactions.
pub fn check_input_is_utxo<B: BlockchainBackend>(db: &B, input: &TransactionInput) -> Result<(), ValidationError> {
let output_hash = input.output_hash();
if let Some(utxo_hash) = db.fetch_unspent_output_hash_by_commitment(input.commitment()?)? {
Expand Down Expand Up @@ -203,7 +204,7 @@ pub fn check_input_is_utxo<B: BlockchainBackend>(db: &B, input: &TransactionInpu

warn!(
target: LOG_TARGET,
"Validation failed due to input: {} which does not exist yet", input
"Input ({}, {}) does not exist in the database yet", input.commitment()?.to_hex(), output_hash.to_hex()
);
Err(ValidationError::UnknownInput)
}
Expand Down
Loading