feat(applying): validate all inputs in UTxO set (#324)
This commit is contained in:
parent
eb4f39d78c
commit
ac4aef4eaa
3 changed files with 45 additions and 3 deletions
|
|
@ -1,18 +1,19 @@
|
|||
//! Utilities required for Byron-era transaction validation.
|
||||
|
||||
use crate::types::{ByronProtParams, UTxOs, ValidationError, ValidationResult};
|
||||
use crate::types::{ByronProtParams, MultiEraInput, UTxOs, ValidationError, ValidationResult};
|
||||
|
||||
use pallas_primitives::byron::{MintedTxPayload, Tx};
|
||||
|
||||
// TODO: implement missing validation rules.
|
||||
pub fn validate_byron_tx(
|
||||
mtxp: &MintedTxPayload,
|
||||
_utxos: &UTxOs,
|
||||
utxos: &UTxOs,
|
||||
_prot_pps: &ByronProtParams,
|
||||
) -> ValidationResult {
|
||||
let tx: &Tx = &mtxp.transaction;
|
||||
check_ins_not_empty(tx)?;
|
||||
check_outs_not_empty(tx)
|
||||
check_outs_not_empty(tx)?;
|
||||
check_ins_in_utxos(tx, utxos)
|
||||
}
|
||||
|
||||
fn check_ins_not_empty(tx: &Tx) -> ValidationResult {
|
||||
|
|
@ -28,3 +29,12 @@ fn check_outs_not_empty(tx: &Tx) -> ValidationResult {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_ins_in_utxos(tx: &Tx, utxos: &UTxOs) -> ValidationResult {
|
||||
for input in tx.inputs.iter() {
|
||||
if !(utxos.contains_key(&MultiEraInput::from_byron(input))) {
|
||||
return Err(ValidationError::InputMissingInUTxO);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ pub enum MultiEraProtParams<'b> {
|
|||
#[derive(Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum ValidationError {
|
||||
InputMissingInUTxO,
|
||||
TxInsEmpty,
|
||||
TxOutsEmpty,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,6 +117,37 @@ mod byron_tests {
|
|||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
// The UTxO set does not contain an entry for the single input to this transaction. This
|
||||
// represents the situation where a transaction tries to spend a non-existent UTxO (e.g., one
|
||||
// which has already been spent).
|
||||
fn unfound_utxo() {
|
||||
let protocol_params: ByronProtParams = ByronProtParams;
|
||||
let mut tx_ins: ByronTxIns = empty_tx_ins();
|
||||
let tx_in: ByronTxIn = new_tx_in(rand_tx_id(), 3);
|
||||
add_byron_tx_in(&mut tx_ins, &tx_in);
|
||||
let mut tx_outs: ByronTxOuts = new_tx_outs();
|
||||
let tx_out_addr: Address = new_addr(rand_addr_payload(), 0);
|
||||
let tx_out: ByronTxOut = new_tx_out(tx_out_addr, 99091);
|
||||
add_tx_out(&mut tx_outs, &tx_out);
|
||||
// Note: utxos is empty, hence the only input to this transaction will not be found, for
|
||||
// which an error should be raised.
|
||||
let utxos: UTxOs = new_utxos();
|
||||
let validation_result = mk_byron_tx_and_validate(
|
||||
&new_tx(tx_ins, tx_outs, empty_attributes()),
|
||||
&empty_witnesses(),
|
||||
&utxos,
|
||||
&protocol_params,
|
||||
);
|
||||
match validation_result {
|
||||
Ok(()) => assert!(false, "All inputs must be within the UTxO set."),
|
||||
Err(err) => match err {
|
||||
ValidationError::InputMissingInUTxO => (),
|
||||
_ => assert!(false, "Unexpected error ({:?}).", err),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Types aliases.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue