Skip to content

Commit

Permalink
refactor: Re-organize and clean-up pallas-primitives (#523)
Browse files Browse the repository at this point in the history
* Re-organize and clean-up pallas-primitives

  Namely:

  - Move _common_ (i.e. era-independent) types and structures up to the
    `lib` module; to be shared across all eras. If any of those deviate
    in a subsequent era, it is easy to bring them down and define new
    types from the point of divergence onward. This simplifies the scope
    of each era-specific module and make them slightly easier to
    navigate.

    Note that, each era module still re-export all of the common types
    that's relevant to that particular era. So technically, this
    reorganization doesn't really change anything for callers/users of
    the library.

  - Rename `Scripthash` to `ScriptHash`. Before this commit, both
    actually existed as `ScriptHash` was introduced with the Conway era.
    Yet, they refer to the same thing, so the duplication is simply
    confusing.

  - Rename `One` / `Two` constructors for `NetworkId` to `Testnet` and
    `Mainnet` respectively. Also defined idiomatic `From` & `TryFrom`
    implementation for conversion to and from `u8`. This is a lot let
    confusing!

  - Generalize `PlutusScript` with a constant generic, to avoid
    repetition for each plutus script generated for specific version.
    Note that a distinction is still _necessary_ if we want to provie
    out-of-the-box serialisers for Plutus scripts, which are serialised
    with a tag prefix depending on the language. All else apart, they
    are strictly similar types.

  - Rename `CostMdls` to `CostModels`. Because, common.

  - Rename `plutus_script` to `plutus_v1_script` in the Alonzo's witness
    set, for consistency with other eras.

* Fix ordering of ScriptHash variants.

  This is an odd one. See the note.

* Bump minicbor to v0.25.1

* Add aliases with deprecation warnings to various fields and types.

* revert renaming plutus_script to plutus_v1_script in Alonzo witness

  See #523 (comment)
  • Loading branch information
KtorZ authored Oct 22, 2024
1 parent 4871342 commit 969d561
Show file tree
Hide file tree
Showing 26 changed files with 973 additions and 1,072 deletions.
55 changes: 29 additions & 26 deletions pallas-applying/src/alonzo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

use crate::utils::{
add_minted_value, add_values, aux_data_from_alonzo_minted_tx, compute_native_script_hash,
compute_plutus_script_hash, empty_value, get_alonzo_comp_tx_size, get_lovelace_from_alonzo_val,
get_network_id_value, get_payment_part, get_shelley_address, get_val_size_in_words,
compute_plutus_v1_script_hash, empty_value, get_alonzo_comp_tx_size,
get_lovelace_from_alonzo_val, get_payment_part, get_shelley_address, get_val_size_in_words,
mk_alonzo_vk_wits_check_list, values_are_equal, verify_signature,
AlonzoError::*,
AlonzoProtParams, UTxOs,
Expand Down Expand Up @@ -159,7 +159,7 @@ fn check_min_fee(
fn presence_of_plutus_scripts(mtx: &MintedTx) -> bool {
let minted_witness_set: &MintedWitnessSet = &mtx.transaction_witness_set;
match &minted_witness_set.plutus_script {
Some(plutus_scripts) => !plutus_scripts.is_empty(),
Some(plutus_v1_scripts) => !plutus_v1_scripts.is_empty(),
None => false,
}
}
Expand Down Expand Up @@ -355,7 +355,7 @@ fn check_tx_outs_network_id(tx_body: &TransactionBody, network_id: &u8) -> Valid
// global network ID.
fn check_tx_network_id(tx_body: &TransactionBody, network_id: &u8) -> ValidationResult {
if let Some(tx_network_id) = tx_body.network_id {
if get_network_id_value(tx_network_id) != *network_id {
if u8::from(tx_network_id) != *network_id {
return Err(Alonzo(TxWrongNetworkID));
}
}
Expand Down Expand Up @@ -402,11 +402,11 @@ fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult {
Some(scripts) => scripts.clone().iter().map(|x| x.clone().unwrap()).collect(),
None => Vec::new(),
};
let plutus_scripts: Vec<PlutusScript> = match &tx_wits.plutus_script {
let plutus_v1_scripts: Vec<PlutusScript<1>> = match &tx_wits.plutus_script {
Some(scripts) => scripts.clone(),
None => Vec::new(),
};
check_needed_scripts_are_included(tx_body, utxos, &native_scripts, &plutus_scripts)?;
check_needed_scripts_are_included(tx_body, utxos, &native_scripts, &plutus_v1_scripts)?;
check_datums(tx_body, utxos, &tx_wits.plutus_data)?;
check_redeemers(tx_body, tx_wits, utxos)?;
check_required_signers(&tx_body.required_signers, vkey_wits, tx_hash)?;
Expand All @@ -420,21 +420,23 @@ fn check_needed_scripts_are_included(
tx_body: &TransactionBody,
utxos: &UTxOs,
native_scripts: &[NativeScript],
plutus_scripts: &[PlutusScript],
plutus_v1_scripts: &[PlutusScript<1>],
) -> ValidationResult {
let mut native_scripts: Vec<(bool, NativeScript)> =
native_scripts.iter().map(|x| (false, x.clone())).collect();
let mut plutus_scripts: Vec<(bool, PlutusScript)> =
plutus_scripts.iter().map(|x| (false, x.clone())).collect();
check_script_inputs(tx_body, &mut native_scripts, &mut plutus_scripts, utxos)?;
check_minting_policies(tx_body, &mut native_scripts, &mut plutus_scripts)?;
let mut plutus_v1_scripts: Vec<(bool, PlutusScript<1>)> = plutus_v1_scripts
.iter()
.map(|x| (false, x.clone()))
.collect();
check_script_inputs(tx_body, &mut native_scripts, &mut plutus_v1_scripts, utxos)?;
check_minting_policies(tx_body, &mut native_scripts, &mut plutus_v1_scripts)?;
for (native_script_covered, _) in native_scripts.iter() {
if !native_script_covered {
return Err(Alonzo(UnneededNativeScript));
}
}
for (plutus_script_covered, _) in plutus_scripts.iter() {
if !plutus_script_covered {
for (plutus_v1_script_covered, _) in plutus_v1_scripts.iter() {
if !plutus_v1_script_covered {
return Err(Alonzo(UnneededPlutusScript));
}
}
Expand Down Expand Up @@ -554,7 +556,7 @@ fn mk_plutus_script_redeemer_pointers(
for (index, input) in sorted_inputs.iter().enumerate() {
if let Some(script_hash) = get_script_hash_from_input(input, utxos) {
for plutus_script in plutus_scripts.iter() {
let hashed_script: PolicyId = compute_plutus_script_hash(plutus_script);
let hashed_script: PolicyId = compute_plutus_v1_script_hash(plutus_script);
if script_hash == hashed_script {
res.push(RedeemerPointer {
tag: RedeemerTag::Spend,
Expand All @@ -569,7 +571,8 @@ fn mk_plutus_script_redeemer_pointers(
let sorted_policies: Vec<PolicyId> = sort_policies(minted_value);
for (index, policy) in sorted_policies.iter().enumerate() {
for plutus_script in plutus_scripts.iter() {
let hashed_script: PolicyId = compute_plutus_script_hash(plutus_script);
let hashed_script: PolicyId =
compute_plutus_v1_script_hash(plutus_script);
if *policy == hashed_script {
res.push(RedeemerPointer {
tag: RedeemerTag::Mint,
Expand Down Expand Up @@ -626,7 +629,7 @@ fn redeemer_pointers_coincide(
fn check_script_inputs(
tx_body: &TransactionBody,
native_scripts: &mut [(bool, NativeScript)],
plutus_scripts: &mut [(bool, PlutusScript)],
plutus_v1_scripts: &mut [(bool, PlutusScript<1>)],
utxos: &UTxOs,
) -> ValidationResult {
let mut inputs: Vec<(bool, ScriptHash)> = get_script_hashes(tx_body, utxos);
Expand All @@ -638,8 +641,8 @@ fn check_script_inputs(
*native_script_covered = true;
}
}
for (plutus_script_covered, plutus_script) in plutus_scripts.iter_mut() {
let hashed_script: PolicyId = compute_plutus_script_hash(plutus_script);
for (plutus_script_covered, plutus_v1_script) in plutus_v1_scripts.iter_mut() {
let hashed_script: PolicyId = compute_plutus_v1_script_hash(plutus_v1_script);
if *input_script_hash == hashed_script {
*input_script_covered = true;
*plutus_script_covered = true;
Expand Down Expand Up @@ -678,7 +681,7 @@ fn get_script_hash_from_input(input: &TransactionInput, utxos: &UTxOs) -> Option
fn check_minting_policies(
tx_body: &TransactionBody,
native_scripts: &mut [(bool, NativeScript)],
plutus_scripts: &mut [(bool, PlutusScript)],
plutus_v1_scripts: &mut [(bool, PlutusScript<1>)],
) -> ValidationResult {
match &tx_body.mint {
None => Ok(()),
Expand All @@ -693,8 +696,8 @@ fn check_minting_policies(
*native_script_covered = true;
}
}
for (plutus_script_covered, plutus_script) in plutus_scripts.iter_mut() {
let hashed_script: PolicyId = compute_plutus_script_hash(plutus_script);
for (plutus_script_covered, plutus_v1_script) in plutus_v1_scripts.iter_mut() {
let hashed_script: PolicyId = compute_plutus_v1_script_hash(plutus_v1_script);
if *policy == hashed_script {
*policy_covered = true;
*plutus_script_covered = true;
Expand Down Expand Up @@ -923,18 +926,18 @@ fn check_minting(tx_body: &TransactionBody, mtx: &MintedTx) -> ValidationResult
.map(|x| x.clone().unwrap())
.collect(),
};
let plutus_script_wits: Vec<PlutusScript> =
let plutus_v1_script_wits: Vec<PlutusScript<1>> =
match &mtx.transaction_witness_set.plutus_script {
None => Vec::new(),
Some(plutus_script_wits) => plutus_script_wits.clone(),
Some(plutus_v1_script_wits) => plutus_v1_script_wits.clone(),
};
for (policy, _) in minted_value.iter() {
if native_script_wits
.iter()
.all(|native_script| compute_native_script_hash(native_script) != *policy)
&& plutus_script_wits
.iter()
.all(|plutus_script| compute_plutus_script_hash(plutus_script) != *policy)
&& plutus_v1_script_wits.iter().all(|plutus_v1_script| {
compute_plutus_v1_script_hash(plutus_v1_script) != *policy
})
{
return Err(Alonzo(MintingLacksPolicy));
}
Expand Down
31 changes: 15 additions & 16 deletions pallas-applying/src/babbage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

use crate::utils::{
add_minted_value, add_values, aux_data_from_babbage_minted_tx, compute_native_script_hash,
compute_plutus_script_hash, compute_plutus_v2_script_hash, empty_value, get_babbage_tx_size,
get_lovelace_from_alonzo_val, get_network_id_value, get_payment_part, get_shelley_address,
get_val_size_in_words, is_byron_address, lovelace_diff_or_fail, mk_alonzo_vk_wits_check_list,
values_are_equal, verify_signature,
compute_plutus_v1_script_hash, compute_plutus_v2_script_hash, empty_value, get_babbage_tx_size,
get_lovelace_from_alonzo_val, get_payment_part, get_shelley_address, get_val_size_in_words,
is_byron_address, lovelace_diff_or_fail, mk_alonzo_vk_wits_check_list, values_are_equal,
verify_signature,
BabbageError::*,
BabbageProtParams, UTxOs,
ValidationError::{self, *},
Expand All @@ -16,15 +16,14 @@ use pallas_codec::{
minicbor::{encode, Encoder},
utils::{Bytes, KeepRaw},
};
use pallas_crypto::hash::Hash;
use pallas_primitives::{
alonzo::{RedeemerPointer, RedeemerTag},
babbage::{
AddrKeyhash, Language, Mint, MintedTransactionBody, MintedTransactionOutput, MintedTx,
MintedWitnessSet, NativeScript, PlutusData, PlutusV1Script, PlutusV2Script, PolicyId,
PseudoDatumOption, PseudoScript, PseudoTransactionOutput, Redeemer, RequiredSigners,
TransactionInput, VKeyWitness, Value,
Language, Mint, MintedTransactionBody, MintedTransactionOutput, MintedTx, MintedWitnessSet,
NativeScript, PseudoDatumOption, PseudoScript, PseudoTransactionOutput, Redeemer,
RequiredSigners, VKeyWitness, Value,
},
AddrKeyhash, Hash, PlutusData, PlutusScript, PolicyId, TransactionInput,
};
use pallas_traverse::{MultiEraInput, MultiEraOutput, OriginalHash};
use std::ops::Deref;
Expand Down Expand Up @@ -166,11 +165,11 @@ fn check_min_fee(

fn presence_of_plutus_scripts(mtx: &MintedTx) -> bool {
let minted_witness_set: &MintedWitnessSet = &mtx.transaction_witness_set;
let plutus_v1_scripts: &[PlutusV1Script] = &minted_witness_set
let plutus_v1_scripts: &[PlutusScript<1>] = &minted_witness_set
.plutus_v1_script
.clone()
.unwrap_or_default();
let plutus_v2_scripts: &[PlutusV2Script] = &minted_witness_set
let plutus_v2_scripts: &[PlutusScript<2>] = &minted_witness_set
.plutus_v2_script
.clone()
.unwrap_or_default();
Expand Down Expand Up @@ -401,7 +400,7 @@ fn check_tx_outs_network_id(tx_body: &MintedTransactionBody, network_id: &u8) ->
// global network ID.
fn check_tx_network_id(tx_body: &MintedTransactionBody, network_id: &u8) -> ValidationResult {
if let Some(tx_network_id) = tx_body.network_id {
if get_network_id_value(tx_network_id) != *network_id {
if u8::from(tx_network_id) != *network_id {
return Err(Babbage(TxWrongNetworkID));
}
}
Expand Down Expand Up @@ -449,12 +448,12 @@ fn check_minting(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationR
.map(|x| x.clone().unwrap())
.collect(),
};
let v1_script_wits: Vec<PlutusV1Script> =
let v1_script_wits: Vec<PlutusScript<1>> =
match &mtx.transaction_witness_set.plutus_v1_script {
None => Vec::new(),
Some(v1_script_wits) => v1_script_wits.clone(),
};
let v2_script_wits: Vec<PlutusV2Script> =
let v2_script_wits: Vec<PlutusScript<2>> =
match &mtx.transaction_witness_set.plutus_v2_script {
None => Vec::new(),
Some(v2_script_wits) => v2_script_wits.clone(),
Expand All @@ -465,7 +464,7 @@ fn check_minting(tx_body: &MintedTransactionBody, mtx: &MintedTx) -> ValidationR
.all(|script| compute_native_script_hash(script) != *policy)
&& v1_script_wits
.iter()
.all(|script| compute_plutus_script_hash(script) != *policy)
.all(|script| compute_plutus_v1_script_hash(script) != *policy)
&& v2_script_wits
.iter()
.all(|script| compute_plutus_v2_script_hash(script) != *policy)
Expand Down Expand Up @@ -500,7 +499,7 @@ fn check_witness_set(mtx: &MintedTx, utxos: &UTxOs) -> ValidationResult {
Some(scripts) => scripts
.clone()
.iter()
.map(compute_plutus_script_hash)
.map(compute_plutus_v1_script_hash)
.collect(),
None => Vec::new(),
};
Expand Down
28 changes: 16 additions & 12 deletions pallas-applying/src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ use pallas_codec::{
use pallas_crypto::key::ed25519::{PublicKey, Signature};
use pallas_primitives::{
alonzo::{
AddrKeyhash, AssetName, AuxiliaryData, Coin, Epoch, GenesisDelegateHash, Genesishash,
MintedTx as AlonzoMintedTx, Multiasset, NativeScript, NetworkId, PlutusScript, PolicyId,
PoolKeyhash, PoolMetadata, Relay, RewardAccount, StakeCredential, TransactionIndex,
UnitInterval, VKeyWitness, Value, VrfKeyhash,
AuxiliaryData, MintedTx as AlonzoMintedTx, Multiasset, NativeScript, VKeyWitness, Value,
},
babbage::{MintedTx as BabbageMintedTx, PlutusV2Script},
babbage::MintedTx as BabbageMintedTx,
AddrKeyhash, AssetName, Coin, Epoch, GenesisDelegateHash, Genesishash, NetworkId, PlutusScript,
PolicyId, PoolKeyhash, PoolMetadata, Relay, RewardAccount, StakeCredential, TransactionIndex,
UnitInterval, VrfKeyhash,
};
use pallas_traverse::{time::Slot, MultiEraInput, MultiEraOutput};
use std::collections::HashMap;
Expand Down Expand Up @@ -267,11 +267,9 @@ pub fn get_lovelace_from_alonzo_val(val: &Value) -> Coin {
}
}

#[deprecated(since = "0.31.0", note = "use `u8::from(...)` instead")]
pub fn get_network_id_value(network_id: NetworkId) -> u8 {
match network_id {
NetworkId::One => 0,
NetworkId::Two => 1,
}
u8::from(network_id)
}

pub fn mk_alonzo_vk_wits_check_list(
Expand Down Expand Up @@ -337,13 +335,18 @@ pub fn compute_native_script_hash(script: &NativeScript) -> PolicyId {
pallas_crypto::hash::Hasher::<224>::hash(&payload)
}

pub fn compute_plutus_script_hash(script: &PlutusScript) -> PolicyId {
#[deprecated(since = "0.31.0", note = "use `compute_plutus_v1_script_hash` instead")]
pub fn compute_plutus_script_hash(script: &PlutusScript<1>) -> PolicyId {
compute_plutus_v1_script_hash(script)
}

pub fn compute_plutus_v1_script_hash(script: &PlutusScript<1>) -> PolicyId {
let mut payload: Vec<u8> = Vec::from(script.as_ref());
payload.insert(0, 1);
pallas_crypto::hash::Hasher::<224>::hash(&payload)
}

pub fn compute_plutus_v2_script_hash(script: &PlutusV2Script) -> PolicyId {
pub fn compute_plutus_v2_script_hash(script: &PlutusScript<2>) -> PolicyId {
let mut payload: Vec<u8> = Vec::from(script.as_ref());
payload.insert(0, 2);
pallas_crypto::hash::Hasher::<224>::hash(&payload)
Expand Down Expand Up @@ -375,7 +378,8 @@ pub struct DState {
pub inst_rewards: InstantaneousRewards,
}

// Essentially part of the `PoolRegistration` component of `Certificate` at alonzo/src/model.rs
// Essentially part of the `PoolRegistration` component of `Certificate` at
// alonzo/src/model.rs
#[derive(Clone, Debug)]
pub struct PoolParam {
pub vrf_keyhash: VrfKeyhash,
Expand Down
13 changes: 7 additions & 6 deletions pallas-applying/src/utils/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
//! era.
use pallas_primitives::{
alonzo::{
Coin, CostMdls, ExUnitPrices, ExUnits, Nonce, ProtocolVersion, RationalNumber, UnitInterval,
Coin, CostModels, ExUnitPrices, ExUnits, Nonce, ProtocolVersion, RationalNumber,
UnitInterval,
},
babbage::CostMdls as BabbageCostMdls,
conway::{CostMdls as ConwayCostMdls, Epoch},
babbage::CostModels as BabbageCostModels,
conway::{CostModels as ConwayCostModels, Epoch},
};

#[allow(clippy::large_enum_variant)]
Expand Down Expand Up @@ -100,7 +101,7 @@ pub struct AlonzoProtParams {
pub protocol_version: ProtocolVersion,
pub min_pool_cost: Coin,
pub ada_per_utxo_byte: Coin,
pub cost_models_for_script_languages: CostMdls,
pub cost_models_for_script_languages: CostModels,
pub execution_costs: ExUnitPrices,
pub max_tx_ex_units: ExUnits,
pub max_block_ex_units: ExUnits,
Expand Down Expand Up @@ -128,7 +129,7 @@ pub struct BabbageProtParams {
pub protocol_version: ProtocolVersion,
pub min_pool_cost: Coin,
pub ada_per_utxo_byte: Coin,
pub cost_models_for_script_languages: BabbageCostMdls,
pub cost_models_for_script_languages: BabbageCostModels,
pub execution_costs: ExUnitPrices,
pub max_tx_ex_units: ExUnits,
pub max_block_ex_units: ExUnits,
Expand Down Expand Up @@ -156,7 +157,7 @@ pub struct ConwayProtParams {
pub protocol_version: ProtocolVersion,
pub min_pool_cost: Coin,
pub ada_per_utxo_byte: Coin,
pub cost_models_for_script_languages: ConwayCostMdls,
pub cost_models_for_script_languages: ConwayCostModels,
pub execution_costs: ExUnitPrices,
pub max_tx_ex_units: ExUnits,
pub max_block_ex_units: ExUnits,
Expand Down
6 changes: 2 additions & 4 deletions pallas-applying/tests/alonzo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,7 @@ mod alonzo_tests {
),
(
// (tx hash, tx output index):
// (d2f9764fa93ae5bcabbb65c7a2f97d1e31188064ae3d2ba1462114453928dd99, 0)
// (d2f9764fa93ae5bcabbb65c7a2f97d1e31188064ae3d2ba1462114453928dd99, 0)
String::from("01c81ffcbc08ff49965d74f90c391541ff1cc2b043ffe41c81d840be8729f2ae5ed49a1734823ba37fd09923f5f7d494ae0efa23dd98ce02da"),
Value::Coin(20292207),
None,
Expand Down Expand Up @@ -1152,9 +1152,7 @@ mod alonzo_tests {
let cbor_bytes: Vec<u8> = cbor_to_bytes(include_str!("../../test_data/alonzo1.tx"));
let mut mtx: MintedTx = minted_tx_from_cbor(&cbor_bytes);
let mut tx_body: TransactionBody = (*mtx.transaction_body).clone();
// Note that NetworkId::One maps to 0 through
// crate::utils::get_network_id_value, which is not correct in mainnet.
tx_body.network_id = Some(NetworkId::One);
tx_body.network_id = Some(NetworkId::Testnet);
let mut tx_buf: Vec<u8> = Vec::new();
let _ = encode(tx_body, &mut tx_buf);
mtx.transaction_body =
Expand Down
Loading

0 comments on commit 969d561

Please sign in to comment.