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(applying): every input is a valid UTxO #324

Merged
merged 1 commit into from
Nov 7, 2023
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
16 changes: 13 additions & 3 deletions pallas-applying/src/byron.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -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(())
}
1 change: 1 addition & 0 deletions pallas-applying/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ pub enum MultiEraProtParams<'b> {
#[derive(Debug)]
#[non_exhaustive]
pub enum ValidationError {
InputMissingInUTxO,
TxInsEmpty,
TxOutsEmpty,
}
Expand Down
31 changes: 31 additions & 0 deletions pallas-applying/tests/byron.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading