refactor: Re-organize and clean-up pallas-primitives (#523)
* 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 https://github.com/txpipe/pallas/pull/523#discussion_r1807329742
This commit is contained in:
parent
4871342a8d
commit
969d5612b7
26 changed files with 972 additions and 1071 deletions
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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)?;
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
@ -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);
|
||||
|
|
@ -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;
|
||||
|
|
@ -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(()),
|
||||
|
|
@ -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;
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, *},
|
||||
|
|
@ -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;
|
||||
|
|
@ -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();
|
||||
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
@ -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(),
|
||||
|
|
@ -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)
|
||||
|
|
@ -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(),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
@ -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(
|
||||
|
|
@ -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)
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)]
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -19,7 +19,7 @@ default = []
|
|||
|
||||
[dependencies]
|
||||
hex = "0.4.3"
|
||||
minicbor = { version = "0.20", features = ["std", "half", "derive"] }
|
||||
minicbor = { version = "0.25.1", features = ["std", "half", "derive"] }
|
||||
num-bigint = { version = "0.4.4", optional = true }
|
||||
serde = { version = "1.0.143", features = ["derive"] }
|
||||
thiserror = "1.0.39"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
use minicbor::{
|
||||
data::{Tag, Type},
|
||||
data::{IanaTag, Tag, Type},
|
||||
decode::Error,
|
||||
Decode, Encode,
|
||||
};
|
||||
|
|
@ -543,7 +543,7 @@ where
|
|||
minicbor::encode::Error::message("error encoding cbor-wrapped structure")
|
||||
})?;
|
||||
|
||||
e.tag(Tag::Cbor)?;
|
||||
e.tag(IanaTag::Cbor)?;
|
||||
e.bytes(&buf)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -587,7 +587,7 @@ where
|
|||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(T))?;
|
||||
e.tag(Tag::new(T))?;
|
||||
e.encode_with(&self.0, ctx)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -741,7 +741,7 @@ where
|
|||
if d.datatype()? == Type::Tag {
|
||||
let found_tag = d.tag()?;
|
||||
|
||||
if found_tag != Tag::Unassigned(TAG_SET) {
|
||||
if found_tag != Tag::new(TAG_SET) {
|
||||
return Err(Error::message(format!("Unrecognised tag: {found_tag:?}")));
|
||||
}
|
||||
}
|
||||
|
|
@ -759,7 +759,7 @@ where
|
|||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(TAG_SET))?;
|
||||
e.tag(Tag::new(TAG_SET))?;
|
||||
e.encode_with(&self.0, ctx)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -824,7 +824,7 @@ where
|
|||
if d.datatype()? == Type::Tag {
|
||||
let found_tag = d.tag()?;
|
||||
|
||||
if found_tag != Tag::Unassigned(TAG_SET) {
|
||||
if found_tag != Tag::new(TAG_SET) {
|
||||
return Err(Error::message(format!("Unrecognised tag: {found_tag:?}")));
|
||||
}
|
||||
}
|
||||
|
|
@ -848,7 +848,7 @@ where
|
|||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(TAG_SET))?;
|
||||
e.tag(Tag::new(TAG_SET))?;
|
||||
e.encode_with(&self.0, ctx)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ impl From<CostModel> for pallas_primitives::alonzo::CostModel {
|
|||
#[derive(Deserialize, Clone)]
|
||||
pub struct CostModelPerLanguage(HashMap<Language, CostModel>);
|
||||
|
||||
impl From<CostModelPerLanguage> for pallas_primitives::alonzo::CostMdls {
|
||||
impl From<CostModelPerLanguage> for pallas_primitives::alonzo::CostModels {
|
||||
fn from(value: CostModelPerLanguage) -> Self {
|
||||
let inner = value
|
||||
.0
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use pallas_codec::minicbor::{data::Tag, decode, encode, Decode, Decoder, Encode, Encoder};
|
||||
use pallas_codec::minicbor::{data::IanaTag, decode, encode, Decode, Decoder, Encode, Encoder};
|
||||
|
||||
use super::Message;
|
||||
|
||||
|
|
@ -29,7 +29,7 @@ impl Encode<()> for Message {
|
|||
}
|
||||
Message::Block { body } => {
|
||||
e.array(2)?.u16(4)?;
|
||||
e.tag(Tag::Cbor)?;
|
||||
e.tag(IanaTag::Cbor)?;
|
||||
e.bytes(body)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -186,10 +186,10 @@ impl Encode<()> for HeaderContent {
|
|||
return Err(Error::message("header variant 0 but no byron prefix"));
|
||||
}
|
||||
|
||||
e.tag(minicbor::data::Tag::Cbor)?;
|
||||
e.tag(minicbor::data::IanaTag::Cbor)?;
|
||||
e.bytes(&self.cbor)?;
|
||||
} else {
|
||||
e.tag(minicbor::data::Tag::Cbor)?;
|
||||
e.tag(minicbor::data::IanaTag::Cbor)?;
|
||||
e.bytes(&self.cbor)?;
|
||||
}
|
||||
|
||||
|
|
@ -211,7 +211,7 @@ impl Encode<()> for BlockContent {
|
|||
e: &mut Encoder<W>,
|
||||
_ctx: &mut (),
|
||||
) -> Result<(), encode::Error<W::Error>> {
|
||||
e.tag(minicbor::data::Tag::Cbor)?;
|
||||
e.tag(minicbor::data::IanaTag::Cbor)?;
|
||||
e.bytes(&self.0)?;
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ impl Encode<()> for BlockQuery {
|
|||
|
||||
if !pools.is_empty() {
|
||||
e.array(1)?;
|
||||
e.tag(Tag::Unassigned(258))?;
|
||||
e.tag(Tag::new(258))?;
|
||||
}
|
||||
|
||||
e.encode(pools)?;
|
||||
|
|
@ -330,7 +330,7 @@ impl<C> minicbor::encode::Encode<C> for RationalNumber {
|
|||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(30))?;
|
||||
e.tag(Tag::new(30))?;
|
||||
e.array(2)?;
|
||||
e.encode_with(self.numerator, ctx)?;
|
||||
e.encode_with(self.denominator, ctx)?;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use pallas_codec::minicbor::data::Tag;
|
||||
use pallas_codec::minicbor::data::IanaTag;
|
||||
use pallas_codec::minicbor::{decode, encode, Decode, Decoder, Encode, Encoder};
|
||||
|
||||
use crate::miniprotocols::localtxsubmission::{EraTx, Message, RejectReason};
|
||||
|
|
@ -78,7 +78,7 @@ impl<'b> Decode<'b, ()> for EraTx {
|
|||
d.array()?;
|
||||
let era = d.u16()?;
|
||||
let tag = d.tag()?;
|
||||
if tag != Tag::Cbor {
|
||||
if tag != IanaTag::Cbor.tag() {
|
||||
return Err(decode::Error::message("Expected encoded CBOR data item"));
|
||||
}
|
||||
Ok(EraTx(era, d.bytes()?.to_vec()))
|
||||
|
|
@ -93,7 +93,7 @@ impl Encode<()> for EraTx {
|
|||
) -> Result<(), encode::Error<W::Error>> {
|
||||
e.array(2)?;
|
||||
e.u16(self.0)?;
|
||||
e.tag(Tag::Cbor)?;
|
||||
e.tag(IanaTag::Cbor)?;
|
||||
e.bytes(&self.1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use pallas_codec::minicbor::{data::Tag, decode, encode, Decode, Decoder, Encode, Encoder};
|
||||
use pallas_codec::minicbor::{data::IanaTag, decode, encode, Decode, Decoder, Encode, Encoder};
|
||||
|
||||
use super::{
|
||||
protocol::{Message, TxIdAndSize},
|
||||
|
|
@ -89,7 +89,7 @@ impl<'b> Decode<'b, ()> for EraTxBody {
|
|||
d.array()?;
|
||||
let era = d.u16()?;
|
||||
let tag = d.tag()?;
|
||||
if tag != Tag::Cbor {
|
||||
if tag != IanaTag::Cbor.tag() {
|
||||
return Err(decode::Error::message("Expected encoded CBOR data item"));
|
||||
}
|
||||
Ok(EraTxBody(era, d.bytes()?.to_vec()))
|
||||
|
|
@ -104,7 +104,7 @@ impl Encode<()> for EraTxBody {
|
|||
) -> Result<(), encode::Error<W::Error>> {
|
||||
e.array(2)?;
|
||||
e.u16(self.0)?;
|
||||
e.tag(Tag::Cbor)?;
|
||||
e.tag(IanaTag::Cbor)?;
|
||||
e.bytes(&self.1)?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,18 +3,17 @@
|
|||
//! Handcrafted, idiomatic rust artifacts based on based on the [Alonzo CDDL](https://github.com/input-output-hk/cardano-ledger/blob/master/eras/alonzo/test-suite/cddl-files/alonzo.cddl) file in IOHK repo.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt, hash::Hash as StdHash, ops::Deref};
|
||||
|
||||
use pallas_codec::minicbor::{data::Tag, Decode, Encode};
|
||||
use pallas_crypto::hash::Hash;
|
||||
use pallas_codec::minicbor::{self, data::Tag, Decode, Encode};
|
||||
|
||||
use pallas_codec::utils::{Bytes, Int, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct VrfCert(#[n(0)] pub Bytes, #[n(1)] pub Bytes);
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, Bytes, Coin, CostModel, DatumHash, DnsName, Epoch,
|
||||
ExUnitPrices, ExUnits, GenesisDelegateHash, Genesishash, Hash, IPv4, IPv6, Int, KeepRaw,
|
||||
KeyValuePairs, MaybeIndefArray, Metadata, Metadatum, MetadatumLabel, NetworkId, Nonce,
|
||||
NonceVariant, Nullable, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata, PoolMetadataHash,
|
||||
Port, PositiveInterval, ProtocolVersion, RationalNumber, Relay, RewardAccount, ScriptHash,
|
||||
StakeCredential, TransactionIndex, TransactionInput, UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct HeaderBody {
|
||||
|
|
@ -64,11 +63,6 @@ pub struct HeaderBody {
|
|||
pub protocol_minor: u64,
|
||||
}
|
||||
|
||||
pub type ProtocolVersion = (u64, u64);
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq)]
|
||||
pub struct KesSignature {}
|
||||
|
||||
pub type MintedHeaderBody<'a> = KeepRaw<'a, HeaderBody>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
|
|
@ -100,50 +94,10 @@ impl<'a> From<MintedHeaderBody<'a>> for HeaderBody {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, StdHash,
|
||||
)]
|
||||
pub struct TransactionInput {
|
||||
#[n(0)]
|
||||
pub transaction_id: Hash<32>,
|
||||
|
||||
#[n(1)]
|
||||
pub index: u64,
|
||||
}
|
||||
|
||||
// $nonce /= [ 0 // 1, bytes .size 32 ]
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NonceVariant {
|
||||
#[n(0)]
|
||||
NeutralNonce,
|
||||
|
||||
#[n(1)]
|
||||
Nonce,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Nonce {
|
||||
#[n(0)]
|
||||
pub variant: NonceVariant,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: Option<Hash<32>>,
|
||||
}
|
||||
|
||||
pub type ScriptHash = Hash<28>;
|
||||
|
||||
pub type PolicyId = Hash<28>;
|
||||
|
||||
pub type AssetName = Bytes;
|
||||
|
||||
pub type Multiasset<A> = KeyValuePairs<PolicyId, KeyValuePairs<AssetName, A>>;
|
||||
|
||||
pub type Mint = Multiasset<i64>;
|
||||
|
||||
pub type Coin = u64;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Value {
|
||||
Coin(Coin),
|
||||
|
|
@ -201,15 +155,9 @@ pub struct TransactionOutput {
|
|||
pub amount: Value,
|
||||
|
||||
#[n(2)]
|
||||
pub datum_hash: Option<Hash<32>>,
|
||||
pub datum_hash: Option<DatumHash>,
|
||||
}
|
||||
|
||||
pub type PoolKeyhash = Hash<28>;
|
||||
pub type Epoch = u64;
|
||||
pub type Genesishash = Bytes;
|
||||
pub type GenesisDelegateHash = Bytes;
|
||||
pub type VrfKeyhash = Hash<32>;
|
||||
|
||||
/* move_instantaneous_reward = [ 0 / 1, { * stake_credential => delta_coin } / coin ]
|
||||
; The first field determines where the funds are drawn from.
|
||||
; 0 denotes the reserves, 1 denotes the treasury.
|
||||
|
|
@ -298,7 +246,7 @@ impl<C> minicbor::encode::Encode<C> for InstantaneousRewardTarget {
|
|||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
#[cbor]
|
||||
#[cbor()]
|
||||
pub struct MoveInstantaneousReward {
|
||||
#[n(0)]
|
||||
pub source: InstantaneousRewardSource,
|
||||
|
|
@ -307,180 +255,10 @@ pub struct MoveInstantaneousReward {
|
|||
pub target: InstantaneousRewardTarget,
|
||||
}
|
||||
|
||||
pub type RewardAccount = Bytes;
|
||||
|
||||
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
|
||||
|
||||
pub type RequiredSigners = Vec<AddrKeyhash>;
|
||||
|
||||
pub type Port = u32;
|
||||
pub type IPv4 = Bytes;
|
||||
pub type IPv6 = Bytes;
|
||||
pub type DnsName = String;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Relay {
|
||||
SingleHostAddr(Nullable<Port>, Nullable<IPv4>, Nullable<IPv6>),
|
||||
SingleHostName(Nullable<Port>, DnsName),
|
||||
MultiHostName(DnsName),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for Relay {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(Relay::SingleHostAddr(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
1 => Ok(Relay::SingleHostName(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
2 => Ok(Relay::MultiHostName(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for Relay",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for Relay {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Relay::SingleHostAddr(a, b, c) => {
|
||||
e.array(4)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
e.encode_with(c, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::SingleHostName(a, b) => {
|
||||
e.array(3)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::MultiHostName(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(2, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type PoolMetadataHash = Hash<32>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct PoolMetadata {
|
||||
#[n(0)]
|
||||
pub url: String,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: PoolMetadataHash,
|
||||
}
|
||||
|
||||
pub type AddrKeyhash = Hash<28>;
|
||||
pub type Scripthash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct RationalNumber {
|
||||
pub numerator: u64,
|
||||
pub denominator: u64,
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for RationalNumber {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.tag()?;
|
||||
d.array()?;
|
||||
|
||||
Ok(RationalNumber {
|
||||
numerator: d.decode_with(ctx)?,
|
||||
denominator: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for RationalNumber {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// TODO: check if this is the correct tag
|
||||
e.tag(Tag::Unassigned(30))?;
|
||||
e.array(2)?;
|
||||
e.encode_with(self.numerator, ctx)?;
|
||||
e.encode_with(self.denominator, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type UnitInterval = RationalNumber;
|
||||
|
||||
pub type PositiveInterval = RationalNumber;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Hash)]
|
||||
pub enum StakeCredential {
|
||||
AddrKeyhash(AddrKeyhash),
|
||||
Scripthash(Scripthash),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for StakeCredential {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(StakeCredential::AddrKeyhash(d.decode_with(ctx)?)),
|
||||
1 => Ok(StakeCredential::Scripthash(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for StakeCredential",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for StakeCredential {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
StakeCredential::AddrKeyhash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
StakeCredential::Scripthash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Certificate {
|
||||
StakeRegistration(StakeCredential),
|
||||
|
|
@ -649,17 +427,6 @@ impl<C> minicbor::encode::Encode<C> for Certificate {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
|
||||
)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NetworkId {
|
||||
#[n(0)]
|
||||
One,
|
||||
#[n(1)]
|
||||
Two,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -667,9 +434,10 @@ pub enum Language {
|
|||
PlutusV1,
|
||||
}
|
||||
|
||||
pub type CostModel = Vec<i64>;
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
pub type CostMdls = KeyValuePairs<Language, CostModel>;
|
||||
pub type CostModels = KeyValuePairs<Language, CostModel>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
|
|
@ -709,7 +477,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -862,380 +630,6 @@ impl<C> minicbor::encode::Encode<C> for NativeScript {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusScript(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusScript {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined to encode PlutusData bytestring as it is done in the canonical
|
||||
/// plutus implementation
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(into = "String")]
|
||||
#[serde(try_from = "String")]
|
||||
pub struct BoundedBytes(Vec<u8>);
|
||||
|
||||
impl From<Vec<u8>> for BoundedBytes {
|
||||
fn from(xs: Vec<u8>) -> Self {
|
||||
BoundedBytes(xs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for Vec<u8> {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
b.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for BoundedBytes {
|
||||
type Target = Vec<u8>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for BoundedBytes {
|
||||
type Error = hex::FromHexError;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
let v = hex::decode(value)?;
|
||||
Ok(BoundedBytes(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for String {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
hex::encode(b.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BoundedBytes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let bytes: Vec<u8> = self.clone().into();
|
||||
|
||||
f.write_str(&hex::encode(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Encode<C> for BoundedBytes {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
_: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// we match the haskell implementation by encoding bytestrings longer than 64
|
||||
// bytes as indefinite lists of bytes
|
||||
const CHUNK_SIZE: usize = 64;
|
||||
let bs: &Vec<u8> = self.deref();
|
||||
if bs.len() <= 64 {
|
||||
e.bytes(bs)?;
|
||||
} else {
|
||||
e.begin_bytes()?;
|
||||
for b in bs.chunks(CHUNK_SIZE) {
|
||||
e.bytes(b)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BoundedBytes {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, _: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let mut res = Vec::new();
|
||||
for chunk in d.bytes_iter()? {
|
||||
let bs = chunk?;
|
||||
res.extend_from_slice(bs);
|
||||
}
|
||||
Ok(BoundedBytes::from(res))
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
big_int = int / big_uint / big_nint ; New
|
||||
big_uint = #6.2(bounded_bytes) ; New
|
||||
big_nint = #6.3(bounded_bytes) ; New
|
||||
*/
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum BigInt {
|
||||
Int(Int),
|
||||
BigUInt(BoundedBytes),
|
||||
BigNInt(BoundedBytes),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BigInt {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let datatype = d.datatype()?;
|
||||
|
||||
match datatype {
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => Ok(Self::Int(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Tag => {
|
||||
let tag = d.tag()?;
|
||||
|
||||
match tag {
|
||||
minicbor::data::Tag::PosBignum => Ok(Self::BigUInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Tag::NegBignum => Ok(Self::BigNInt(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor tag for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor data type for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for BigInt {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
BigInt::Int(x) => {
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigUInt(x) => {
|
||||
e.tag(Tag::PosBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigNInt(x) => {
|
||||
e.tag(Tag::NegBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum PlutusData {
|
||||
Constr(Constr<PlutusData>),
|
||||
Map(KeyValuePairs<PlutusData, PlutusData>),
|
||||
BigInt(BigInt),
|
||||
BoundedBytes(BoundedBytes),
|
||||
Array(Vec<PlutusData>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let type_ = d.datatype()?;
|
||||
|
||||
match type_ {
|
||||
minicbor::data::Type::Tag => {
|
||||
let mut probe = d.probe();
|
||||
let tag = probe.tag()?;
|
||||
|
||||
match tag {
|
||||
Tag::Unassigned(121..=127 | 1280..=1400 | 102) => {
|
||||
Ok(Self::Constr(d.decode_with(ctx)?))
|
||||
}
|
||||
Tag::PosBignum | Tag::NegBignum => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"unknown tag for plutus data tag",
|
||||
)),
|
||||
}
|
||||
}
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Self::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Self::BoundedBytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::BytesIndef => {
|
||||
let mut full = Vec::new();
|
||||
|
||||
for slice in d.bytes_iter()? {
|
||||
full.extend(slice?);
|
||||
}
|
||||
|
||||
Ok(Self::BoundedBytes(BoundedBytes::from(full)))
|
||||
}
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Self::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
|
||||
any => Err(minicbor::decode::Error::message(format!(
|
||||
"bad cbor data type ({any:?}) for plutus data"
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_list<C, W: minicbor::encode::Write, A: minicbor::encode::Encode<C>>(
|
||||
a: &Vec<A>,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// Mimics default haskell list encoding from cborg:
|
||||
// We use indef array for non-empty arrays but definite 0-length array for empty
|
||||
if a.is_empty() {
|
||||
e.array(0)?;
|
||||
} else {
|
||||
e.begin_array()?;
|
||||
for v in a {
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for PlutusData {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Self::Constr(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Map(a) => {
|
||||
// we use definite array to match the approach used by haskell's plutus
|
||||
// implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.map(a.len().try_into().unwrap())?;
|
||||
for (k, v) in a.iter() {
|
||||
k.encode(e, ctx)?;
|
||||
v.encode(e, ctx)?;
|
||||
}
|
||||
}
|
||||
Self::BigInt(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::BoundedBytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Array(a) => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L153
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(a, e, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub struct Constr<A> {
|
||||
pub tag: u64,
|
||||
pub any_constructor: Option<u64>,
|
||||
pub fields: Vec<A>,
|
||||
}
|
||||
|
||||
impl<'b, C, A> minicbor::decode::Decode<'b, C> for Constr<A>
|
||||
where
|
||||
A: minicbor::decode::Decode<'b, C>,
|
||||
{
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let tag = d.tag()?;
|
||||
|
||||
match tag {
|
||||
Tag::Unassigned(x) => match x {
|
||||
121..=127 | 1280..=1400 => Ok(Constr {
|
||||
tag: x,
|
||||
fields: d.decode_with(ctx)?,
|
||||
any_constructor: None,
|
||||
}),
|
||||
102 => {
|
||||
d.array()?;
|
||||
|
||||
Ok(Constr {
|
||||
tag: x,
|
||||
any_constructor: Some(d.decode_with(ctx)?),
|
||||
fields: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
},
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, A> minicbor::encode::Encode<C> for Constr<A>
|
||||
where
|
||||
A: minicbor::encode::Encode<C>,
|
||||
{
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::Unassigned(self.tag))?;
|
||||
|
||||
match self.tag {
|
||||
102 => {
|
||||
// definite length array here
|
||||
// https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.array(2)?;
|
||||
e.encode_with(self.any_constructor.unwrap_or_default(), ctx)?;
|
||||
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L144
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation. See above reference.
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct ExUnits {
|
||||
#[n(0)]
|
||||
pub mem: u64,
|
||||
#[n(1)]
|
||||
pub steps: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
pub mem_price: PositiveInterval,
|
||||
|
||||
#[n(1)]
|
||||
pub step_price: PositiveInterval,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
#[cbor(index_only)]
|
||||
pub enum RedeemerTag {
|
||||
|
|
@ -1308,7 +702,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_script: Option<Vec<PlutusScript>>,
|
||||
pub plutus_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<Vec<PlutusData>>,
|
||||
|
|
@ -1330,7 +724,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_script: Option<Vec<PlutusScript>>,
|
||||
pub plutus_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<Vec<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -1340,6 +734,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
#[allow(deprecated)]
|
||||
fn from(x: MintedWitnessSet<'b>) -> Self {
|
||||
WitnessSet {
|
||||
vkeywitness: x.vkeywitness,
|
||||
|
|
@ -1366,80 +761,9 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_scripts: Option<Vec<PlutusScript>>,
|
||||
pub plutus_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum Metadatum {
|
||||
Int(Int),
|
||||
Bytes(Bytes),
|
||||
Text(String),
|
||||
Array(Vec<Metadatum>),
|
||||
Map(KeyValuePairs<Metadatum, Metadatum>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for Metadatum {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
match d.datatype()? {
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => {
|
||||
let i = d.decode()?;
|
||||
Ok(Metadatum::Int(i))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Metadatum::Bytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::String => Ok(Metadatum::Text(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Metadatum::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Metadatum::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"Can't turn data type into metadatum",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::Encode<C> for Metadatum {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Metadatum::Int(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Bytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Text(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Array(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Map(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type MetadatumLabel = u64;
|
||||
|
||||
pub type Metadata = KeyValuePairs<MetadatumLabel, Metadatum>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct ShelleyMaAuxiliaryData {
|
||||
#[n(0)]
|
||||
|
|
@ -1489,7 +813,7 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
|
|||
}
|
||||
AuxiliaryData::PostAlonzo(v) => {
|
||||
// TODO: check if this is the correct tag
|
||||
e.tag(Tag::Unassigned(259))?;
|
||||
e.tag(Tag::new(259))?;
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
};
|
||||
|
|
@ -1498,8 +822,6 @@ impl<C> minicbor::Encode<C> for AuxiliaryData {
|
|||
}
|
||||
}
|
||||
|
||||
pub type TransactionIndex = u32;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct Block {
|
||||
#[n(0)]
|
||||
|
|
|
|||
|
|
@ -4,15 +4,19 @@
|
|||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use pallas_codec::minicbor::{Decode, Encode};
|
||||
use pallas_codec::{
|
||||
minicbor::{self, Decode, Encode},
|
||||
utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable},
|
||||
};
|
||||
use pallas_crypto::hash::{Hash, Hasher};
|
||||
|
||||
use pallas_codec::utils::{Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, Nullable};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
use crate::alonzo::VrfCert;
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, DatumHash, DnsName, Epoch, ExUnitPrices, ExUnits,
|
||||
GenesisDelegateHash, Genesishash, IPv4, IPv6, Metadata, Metadatum, MetadatumLabel, NetworkId,
|
||||
Nonce, NonceVariant, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata, PoolMetadataHash, Port,
|
||||
PositiveInterval, ProtocolVersion, RationalNumber, Relay, ScriptHash, StakeCredential,
|
||||
TransactionIndex, TransactionInput, UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct HeaderBody {
|
||||
|
|
@ -62,10 +66,6 @@ pub struct OperationalCert {
|
|||
pub operational_cert_sigma: Bytes,
|
||||
}
|
||||
|
||||
pub use crate::alonzo::ProtocolVersion;
|
||||
|
||||
pub use crate::alonzo::KesSignature;
|
||||
|
||||
pub type MintedHeaderBody<'a> = KeepRaw<'a, HeaderBody>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
|
|
@ -97,18 +97,6 @@ impl<'a> From<MintedHeaderBody<'a>> for HeaderBody {
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::TransactionInput;
|
||||
|
||||
pub use crate::alonzo::NonceVariant;
|
||||
|
||||
pub use crate::alonzo::Nonce;
|
||||
|
||||
pub use crate::alonzo::ScriptHash;
|
||||
|
||||
pub use crate::alonzo::PolicyId;
|
||||
|
||||
pub use crate::alonzo::AssetName;
|
||||
|
||||
pub use crate::alonzo::Multiasset;
|
||||
|
||||
pub use crate::alonzo::Mint;
|
||||
|
|
@ -119,16 +107,6 @@ pub use crate::alonzo::Value;
|
|||
|
||||
pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
|
||||
|
||||
pub use crate::alonzo::PoolKeyhash;
|
||||
|
||||
pub use crate::alonzo::Epoch;
|
||||
|
||||
pub use crate::alonzo::Genesishash;
|
||||
|
||||
pub use crate::alonzo::GenesisDelegateHash;
|
||||
|
||||
pub use crate::alonzo::VrfKeyhash;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardSource;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardTarget;
|
||||
|
|
@ -137,40 +115,12 @@ pub use crate::alonzo::MoveInstantaneousReward;
|
|||
|
||||
pub use crate::alonzo::RewardAccount;
|
||||
|
||||
pub type Withdrawals = KeyValuePairs<RewardAccount, Coin>;
|
||||
pub use crate::alonzo::Withdrawals;
|
||||
|
||||
pub type RequiredSigners = Vec<AddrKeyhash>;
|
||||
|
||||
pub use crate::alonzo::Port;
|
||||
|
||||
pub use crate::alonzo::IPv4;
|
||||
|
||||
pub use crate::alonzo::IPv6;
|
||||
|
||||
pub use crate::alonzo::DnsName;
|
||||
|
||||
pub use crate::alonzo::Relay;
|
||||
|
||||
pub use crate::alonzo::PoolMetadataHash;
|
||||
|
||||
pub use crate::alonzo::PoolMetadata;
|
||||
|
||||
pub use crate::alonzo::AddrKeyhash;
|
||||
|
||||
pub use crate::alonzo::Scripthash;
|
||||
|
||||
pub use crate::alonzo::RationalNumber;
|
||||
|
||||
pub use crate::alonzo::UnitInterval;
|
||||
|
||||
pub use crate::alonzo::PositiveInterval;
|
||||
|
||||
pub use crate::alonzo::StakeCredential;
|
||||
pub use crate::alonzo::RequiredSigners;
|
||||
|
||||
pub use crate::alonzo::Certificate;
|
||||
|
||||
pub use crate::alonzo::NetworkId;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -181,11 +131,14 @@ pub enum Language {
|
|||
PlutusV2,
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
pub use crate::alonzo::CostModel;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
pub struct CostMdls {
|
||||
pub struct CostModels {
|
||||
#[n(0)]
|
||||
pub plutus_v1: Option<CostModel>,
|
||||
|
||||
|
|
@ -228,7 +181,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -455,28 +408,6 @@ pub use crate::alonzo::VKeyWitness;
|
|||
|
||||
pub use crate::alonzo::NativeScript;
|
||||
|
||||
pub use crate::alonzo::PlutusScript as PlutusV1Script;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusV2Script(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusV2Script {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::BigInt;
|
||||
|
||||
pub use crate::alonzo::PlutusData;
|
||||
|
||||
pub use crate::alonzo::Constr;
|
||||
|
||||
pub use crate::alonzo::ExUnits;
|
||||
|
||||
pub use crate::alonzo::ExUnitPrices;
|
||||
|
||||
pub use crate::alonzo::RedeemerTag;
|
||||
|
||||
pub use crate::alonzo::Redeemer;
|
||||
|
|
@ -496,7 +427,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<Vec<PlutusData>>,
|
||||
|
|
@ -505,7 +436,7 @@ pub struct WitnessSet {
|
|||
pub redeemer: Option<Vec<Redeemer>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
@ -521,7 +452,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<Vec<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<Vec<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -530,7 +461,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub redeemer: Option<Vec<Redeemer>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
|
|
@ -561,20 +492,16 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
|
||||
}
|
||||
|
||||
pub type DatumHash = Hash<32>;
|
||||
|
||||
//pub type Data = CborWrap<PlutusData>;
|
||||
|
||||
// datum_option = [ 0, $hash32 // 1, data ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoDatumOption<T1> {
|
||||
Hash(Hash<32>),
|
||||
Hash(DatumHash),
|
||||
Data(CborWrap<T1>),
|
||||
}
|
||||
|
||||
|
|
@ -626,12 +553,18 @@ impl<'b> From<MintedDatumOption<'b>> for DatumOption {
|
|||
}
|
||||
}
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
|
||||
pub type PlutusV1Script = PlutusScript<1>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
|
||||
pub type PlutusV2Script = PlutusScript<2>;
|
||||
|
||||
// script = [ 0, native_script // 1, plutus_v1_script // 2, plutus_v2_script ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoScript<T1> {
|
||||
NativeScript(T1),
|
||||
PlutusV1Script(PlutusV1Script),
|
||||
PlutusV2Script(PlutusV2Script),
|
||||
PlutusV1Script(PlutusScript<1>),
|
||||
PlutusV2Script(PlutusScript<2>),
|
||||
}
|
||||
|
||||
// script_ref = #6.24(bytes .cbor script)
|
||||
|
|
@ -689,16 +622,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::Metadatum;
|
||||
|
||||
pub use crate::alonzo::MetadatumLabel;
|
||||
|
||||
pub use crate::alonzo::Metadata;
|
||||
|
||||
pub use crate::alonzo::AuxiliaryData;
|
||||
|
||||
pub use crate::alonzo::TransactionIndex;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
pub struct PseudoBlock<T1, T2, T3, T4>
|
||||
where
|
||||
|
|
|
|||
|
|
@ -2,53 +2,34 @@
|
|||
//!
|
||||
//! Handcrafted, idiomatic rust artifacts based on based on the [Conway CDDL](https://github.com/IntersectMBO/cardano-ledger/blob/master/eras/conway/impl/cddl-files/conway.cddl) file in IntersectMBO repo.
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Deref;
|
||||
|
||||
use pallas_codec::minicbor::decode::Error;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use pallas_codec::minicbor::{self, decode::Error, Decode, Encode};
|
||||
use pallas_codec::utils::CborWrap;
|
||||
|
||||
use pallas_codec::minicbor::{Decode, Encode};
|
||||
use pallas_crypto::hash::Hash;
|
||||
|
||||
use pallas_codec::utils::{
|
||||
Bytes, CborWrap, KeepRaw, KeyValuePairs, MaybeIndefArray, NonEmptyKeyValuePairs, NonEmptySet,
|
||||
NonZeroInt, Nullable, PositiveCoin, Set,
|
||||
pub use crate::{
|
||||
plutus_data::*, AddrKeyhash, AssetName, Bytes, Coin, CostModel, DnsName, Epoch, ExUnits,
|
||||
GenesisDelegateHash, Genesishash, Hash, IPv4, IPv6, KeepRaw, KeyValuePairs, MaybeIndefArray,
|
||||
Metadata, Metadatum, MetadatumLabel, NetworkId, NonEmptyKeyValuePairs, NonEmptySet, NonZeroInt,
|
||||
Nonce, NonceVariant, Nullable, PlutusScript, PolicyId, PoolKeyhash, PoolMetadata,
|
||||
PoolMetadataHash, Port, PositiveCoin, PositiveInterval, ProtocolVersion, RationalNumber, Relay,
|
||||
RewardAccount, ScriptHash, Set, StakeCredential, TransactionIndex, TransactionInput,
|
||||
UnitInterval, VrfCert, VrfKeyhash,
|
||||
};
|
||||
|
||||
// required for derive attrs to work
|
||||
use pallas_codec::minicbor;
|
||||
|
||||
pub use crate::alonzo::VrfCert;
|
||||
|
||||
use crate::babbage;
|
||||
|
||||
pub use crate::babbage::HeaderBody;
|
||||
|
||||
pub use crate::babbage::OperationalCert;
|
||||
|
||||
pub use crate::alonzo::ProtocolVersion;
|
||||
|
||||
pub use crate::alonzo::KesSignature;
|
||||
|
||||
pub use crate::babbage::Header;
|
||||
|
||||
pub use crate::alonzo::TransactionInput;
|
||||
|
||||
pub use crate::alonzo::NonceVariant;
|
||||
|
||||
pub use crate::alonzo::Nonce;
|
||||
|
||||
pub use crate::alonzo::ScriptHash;
|
||||
|
||||
pub use crate::alonzo::PolicyId;
|
||||
|
||||
pub use crate::alonzo::AssetName;
|
||||
|
||||
pub type Multiasset<A> = NonEmptyKeyValuePairs<PolicyId, NonEmptyKeyValuePairs<AssetName, A>>;
|
||||
|
||||
pub type Mint = Multiasset<NonZeroInt>;
|
||||
|
||||
pub use crate::alonzo::Coin;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Value {
|
||||
Coin(Coin),
|
||||
|
|
@ -99,54 +80,10 @@ impl<C> minicbor::encode::Encode<C> for Value {
|
|||
|
||||
pub use crate::alonzo::TransactionOutput as LegacyTransactionOutput;
|
||||
|
||||
pub use crate::alonzo::PoolKeyhash;
|
||||
|
||||
pub use crate::alonzo::Epoch;
|
||||
|
||||
pub use crate::alonzo::Genesishash;
|
||||
|
||||
pub use crate::alonzo::GenesisDelegateHash;
|
||||
|
||||
pub use crate::alonzo::VrfKeyhash;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardSource;
|
||||
|
||||
pub use crate::alonzo::InstantaneousRewardTarget;
|
||||
|
||||
pub use crate::alonzo::MoveInstantaneousReward;
|
||||
|
||||
pub use crate::alonzo::RewardAccount;
|
||||
|
||||
pub type Withdrawals = NonEmptyKeyValuePairs<RewardAccount, Coin>;
|
||||
|
||||
pub type RequiredSigners = NonEmptySet<AddrKeyhash>;
|
||||
|
||||
pub use crate::alonzo::Port;
|
||||
|
||||
pub use crate::alonzo::IPv4;
|
||||
|
||||
pub use crate::alonzo::IPv6;
|
||||
|
||||
pub use crate::alonzo::DnsName;
|
||||
|
||||
pub use crate::alonzo::Relay;
|
||||
|
||||
pub use crate::alonzo::PoolMetadataHash;
|
||||
|
||||
pub use crate::alonzo::PoolMetadata;
|
||||
|
||||
pub use crate::alonzo::AddrKeyhash;
|
||||
|
||||
pub use crate::alonzo::Scripthash;
|
||||
|
||||
pub use crate::alonzo::RationalNumber;
|
||||
|
||||
pub use crate::alonzo::UnitInterval;
|
||||
|
||||
pub use crate::alonzo::PositiveInterval;
|
||||
|
||||
pub use crate::alonzo::StakeCredential;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Certificate {
|
||||
StakeRegistration(StakeCredential),
|
||||
|
|
@ -442,7 +379,7 @@ impl<C> minicbor::encode::Encode<C> for Certificate {
|
|||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone)]
|
||||
pub enum DRep {
|
||||
Key(AddrKeyhash),
|
||||
Script(Scripthash),
|
||||
Script(ScriptHash),
|
||||
Abstain,
|
||||
NoConfidence,
|
||||
}
|
||||
|
|
@ -507,8 +444,6 @@ pub type CommitteeColdCredential = StakeCredential;
|
|||
|
||||
pub type CommitteeHotCredential = StakeCredential;
|
||||
|
||||
pub use crate::alonzo::NetworkId;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum Language {
|
||||
|
|
@ -522,11 +457,12 @@ pub enum Language {
|
|||
PlutusV3,
|
||||
}
|
||||
|
||||
pub use crate::alonzo::CostModel;
|
||||
#[deprecated(since = "0.31.0", note = "use `CostModels` instead")]
|
||||
pub type CostMdls = CostModels;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(map)]
|
||||
pub struct CostMdls {
|
||||
pub struct CostModels {
|
||||
#[n(0)]
|
||||
pub plutus_v1: Option<CostModel>,
|
||||
|
||||
|
|
@ -570,7 +506,7 @@ pub struct ProtocolParamUpdate {
|
|||
#[n(17)]
|
||||
pub ada_per_utxo_byte: Option<Coin>,
|
||||
#[n(18)]
|
||||
pub cost_models_for_script_languages: Option<CostMdls>,
|
||||
pub cost_models_for_script_languages: Option<CostModels>,
|
||||
#[n(19)]
|
||||
pub execution_costs: Option<ExUnitPrices>,
|
||||
#[n(20)]
|
||||
|
|
@ -1285,28 +1221,6 @@ pub use crate::alonzo::VKeyWitness;
|
|||
|
||||
pub use crate::alonzo::NativeScript;
|
||||
|
||||
pub use crate::alonzo::PlutusScript as PlutusV1Script;
|
||||
|
||||
pub use crate::babbage::PlutusV2Script;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusV3Script(#[n(0)] pub Bytes);
|
||||
|
||||
impl AsRef<[u8]> for PlutusV3Script {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::BigInt;
|
||||
|
||||
pub use crate::alonzo::PlutusData;
|
||||
|
||||
pub use crate::alonzo::Constr;
|
||||
|
||||
pub use crate::alonzo::ExUnits;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
|
|
@ -1446,7 +1360,7 @@ pub struct WitnessSet {
|
|||
pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_data: Option<NonEmptySet<PlutusData>>,
|
||||
|
|
@ -1455,10 +1369,10 @@ pub struct WitnessSet {
|
|||
pub redeemer: Option<Redeemers>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
|
||||
|
||||
#[n(7)]
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusV3Script>>,
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
#[derive(Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
@ -1474,7 +1388,7 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub bootstrap_witness: Option<NonEmptySet<BootstrapWitness>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusV1Script>>,
|
||||
pub plutus_v1_script: Option<NonEmptySet<PlutusScript<1>>>,
|
||||
|
||||
#[b(4)]
|
||||
pub plutus_data: Option<NonEmptySet<KeepRaw<'b, PlutusData>>>,
|
||||
|
|
@ -1483,10 +1397,10 @@ pub struct MintedWitnessSet<'b> {
|
|||
pub redeemer: Option<KeepRaw<'b, Redeemers>>,
|
||||
|
||||
#[n(6)]
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusV2Script>>,
|
||||
pub plutus_v2_script: Option<NonEmptySet<PlutusScript<2>>>,
|
||||
|
||||
#[n(7)]
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusV3Script>>,
|
||||
pub plutus_v3_script: Option<NonEmptySet<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
impl<'b> From<MintedWitnessSet<'b>> for WitnessSet {
|
||||
|
|
@ -1514,13 +1428,13 @@ pub struct PostAlonzoAuxiliaryData {
|
|||
pub native_scripts: Option<Vec<NativeScript>>,
|
||||
|
||||
#[n(2)]
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusV1Script>>,
|
||||
pub plutus_v1_scripts: Option<Vec<PlutusScript<1>>>,
|
||||
|
||||
#[n(3)]
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusV2Script>>,
|
||||
pub plutus_v2_scripts: Option<Vec<PlutusScript<2>>>,
|
||||
|
||||
#[n(4)]
|
||||
pub plutus_v3_scripts: Option<Vec<PlutusV3Script>>,
|
||||
pub plutus_v3_scripts: Option<Vec<PlutusScript<3>>>,
|
||||
}
|
||||
|
||||
pub use crate::babbage::DatumHash;
|
||||
|
|
@ -1531,13 +1445,22 @@ pub use crate::babbage::DatumOption;
|
|||
|
||||
pub use crate::babbage::MintedDatumOption;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<1>` instead")]
|
||||
pub type PlutusV1Script = PlutusScript<1>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<2>` instead")]
|
||||
pub type PlutusV2Script = PlutusScript<2>;
|
||||
|
||||
#[deprecated(since = "0.31.0", note = "use `PlutusScript<3>` instead")]
|
||||
pub type PlutusV3Script = PlutusScript<3>;
|
||||
|
||||
// script = [ 0, native_script // 1, plutus_v1_script // 2, plutus_v2_script ]
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
pub enum PseudoScript<T1> {
|
||||
NativeScript(T1),
|
||||
PlutusV1Script(PlutusV1Script),
|
||||
PlutusV2Script(PlutusV2Script),
|
||||
PlutusV3Script(PlutusV3Script),
|
||||
PlutusV1Script(PlutusScript<1>),
|
||||
PlutusV2Script(PlutusScript<2>),
|
||||
PlutusV3Script(PlutusScript<3>),
|
||||
}
|
||||
|
||||
// script_ref = #6.24(bytes .cbor script)
|
||||
|
|
@ -1610,15 +1533,8 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
pub use crate::alonzo::Metadatum;
|
||||
|
||||
pub use crate::alonzo::MetadatumLabel;
|
||||
|
||||
pub use crate::alonzo::Metadata;
|
||||
|
||||
pub use crate::alonzo::AuxiliaryData;
|
||||
|
||||
pub use crate::alonzo::TransactionIndex;
|
||||
use crate::babbage::MintedHeader;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Clone)]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,402 @@
|
|||
//! Ledger primitives and cbor codec for the Cardano eras
|
||||
|
||||
mod framework;
|
||||
mod plutus_data;
|
||||
|
||||
pub mod alonzo;
|
||||
pub mod babbage;
|
||||
pub mod byron;
|
||||
pub mod conway;
|
||||
pub use plutus_data::*;
|
||||
|
||||
pub use framework::*;
|
||||
|
||||
pub use pallas_codec::utils::{
|
||||
Bytes, Int, KeepRaw, KeyValuePairs, MaybeIndefArray, NonEmptyKeyValuePairs, NonEmptySet,
|
||||
NonZeroInt, Nullable, PositiveCoin, Set,
|
||||
};
|
||||
pub use pallas_crypto::hash::Hash;
|
||||
|
||||
use pallas_codec::minicbor::{self, data::Tag, Decode, Encode};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
// ----- Common type definitions
|
||||
|
||||
pub type AddrKeyhash = Hash<28>;
|
||||
|
||||
pub type AssetName = Bytes;
|
||||
|
||||
pub type Coin = u64;
|
||||
|
||||
pub type CostModel = Vec<i64>;
|
||||
|
||||
pub type DatumHash = Hash<32>;
|
||||
|
||||
pub type DnsName = String;
|
||||
|
||||
pub type Epoch = u64;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone, Copy)]
|
||||
pub struct ExUnits {
|
||||
#[n(0)]
|
||||
pub mem: u64,
|
||||
#[n(1)]
|
||||
pub steps: u64,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct ExUnitPrices {
|
||||
#[n(0)]
|
||||
pub mem_price: PositiveInterval,
|
||||
|
||||
#[n(1)]
|
||||
pub step_price: PositiveInterval,
|
||||
}
|
||||
|
||||
pub type Genesishash = Bytes;
|
||||
|
||||
pub type GenesisDelegateHash = Bytes;
|
||||
|
||||
pub type IPv4 = Bytes;
|
||||
|
||||
pub type IPv6 = Bytes;
|
||||
|
||||
pub type Metadata = KeyValuePairs<MetadatumLabel, Metadatum>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum Metadatum {
|
||||
Int(Int),
|
||||
Bytes(Bytes),
|
||||
Text(String),
|
||||
Array(Vec<Metadatum>),
|
||||
Map(KeyValuePairs<Metadatum, Metadatum>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::Decode<'b, C> for Metadatum {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
match d.datatype()? {
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => {
|
||||
let i = d.decode()?;
|
||||
Ok(Metadatum::Int(i))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Metadatum::Bytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::String => Ok(Metadatum::Text(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Metadatum::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Metadatum::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"Can't turn data type into metadatum",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::Encode<C> for Metadatum {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Metadatum::Int(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Bytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Text(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Array(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Metadatum::Map(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub type MetadatumLabel = u64;
|
||||
|
||||
#[derive(
|
||||
Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy,
|
||||
)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NetworkId {
|
||||
#[n(0)]
|
||||
Testnet,
|
||||
#[n(1)]
|
||||
Mainnet,
|
||||
}
|
||||
|
||||
impl From<NetworkId> for u8 {
|
||||
fn from(network_id: NetworkId) -> u8 {
|
||||
match network_id {
|
||||
NetworkId::Testnet => 0,
|
||||
NetworkId::Mainnet => 1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for NetworkId {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(i: u8) -> Result<Self, Self::Error> {
|
||||
match i {
|
||||
0 => Ok(Self::Testnet),
|
||||
1 => Ok(Self::Mainnet),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct Nonce {
|
||||
#[n(0)]
|
||||
pub variant: NonceVariant,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: Option<Hash<32>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(index_only)]
|
||||
pub enum NonceVariant {
|
||||
#[n(0)]
|
||||
NeutralNonce,
|
||||
|
||||
#[n(1)]
|
||||
Nonce,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
#[cbor(transparent)]
|
||||
pub struct PlutusScript<const VERSION: usize>(#[n(0)] pub Bytes);
|
||||
|
||||
impl<const VERSION: usize> AsRef<[u8]> for PlutusScript<VERSION> {
|
||||
fn as_ref(&self) -> &[u8] {
|
||||
self.0.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
pub type PolicyId = Hash<28>;
|
||||
|
||||
pub type PoolKeyhash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct PoolMetadata {
|
||||
#[n(0)]
|
||||
pub url: String,
|
||||
|
||||
#[n(1)]
|
||||
pub hash: PoolMetadataHash,
|
||||
}
|
||||
|
||||
pub type PoolMetadataHash = Hash<32>;
|
||||
|
||||
pub type Port = u32;
|
||||
|
||||
pub type PositiveInterval = RationalNumber;
|
||||
|
||||
pub type ProtocolVersion = (u64, u64);
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct RationalNumber {
|
||||
pub numerator: u64,
|
||||
pub denominator: u64,
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for RationalNumber {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
// TODO: Enforce tag == 30 & array of size 2
|
||||
d.tag()?;
|
||||
d.array()?;
|
||||
Ok(RationalNumber {
|
||||
numerator: d.decode_with(ctx)?,
|
||||
denominator: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for RationalNumber {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::new(30))?;
|
||||
e.array(2)?;
|
||||
e.encode_with(self.numerator, ctx)?;
|
||||
e.encode_with(self.denominator, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Relay {
|
||||
SingleHostAddr(Nullable<Port>, Nullable<IPv4>, Nullable<IPv6>),
|
||||
SingleHostName(Nullable<Port>, DnsName),
|
||||
MultiHostName(DnsName),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for Relay {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(Relay::SingleHostAddr(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
1 => Ok(Relay::SingleHostName(
|
||||
d.decode_with(ctx)?,
|
||||
d.decode_with(ctx)?,
|
||||
)),
|
||||
2 => Ok(Relay::MultiHostName(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for Relay",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for Relay {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Relay::SingleHostAddr(a, b, c) => {
|
||||
e.array(4)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
e.encode_with(c, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::SingleHostName(a, b) => {
|
||||
e.array(3)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
e.encode_with(b, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Relay::MultiHostName(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(2, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type RewardAccount = Bytes;
|
||||
|
||||
pub type ScriptHash = Hash<28>;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, PartialOrd, Eq, Ord, Clone, Hash)]
|
||||
// !! NOTE / IMPORTANT !!
|
||||
// It is tempting to swap the order of the two constructors so that AddrKeyHash
|
||||
// comes first. This indeed nicely maps the binary representation which
|
||||
// associates 0 to AddrKeyHash and 1 to ScriptHash.
|
||||
//
|
||||
// However, for historical reasons, the ScriptHash variant comes first in the
|
||||
// Haskell reference codebase. From this ordering is derived the `PartialOrd`
|
||||
// and `Ord` instances; which impacts how Maps/Dictionnaries indexed by
|
||||
// StakeCredential will be ordered. So, it is crucial to preserve this quirks to
|
||||
// avoid hard to troubleshoot issues down the line.
|
||||
pub enum StakeCredential {
|
||||
ScriptHash(ScriptHash),
|
||||
AddrKeyhash(AddrKeyhash),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for StakeCredential {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
d.array()?;
|
||||
let variant = d.u16()?;
|
||||
|
||||
match variant {
|
||||
0 => Ok(StakeCredential::AddrKeyhash(d.decode_with(ctx)?)),
|
||||
1 => Ok(StakeCredential::ScriptHash(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid variant id for StakeCredential",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for StakeCredential {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
StakeCredential::AddrKeyhash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(0, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
StakeCredential::ScriptHash(a) => {
|
||||
e.array(2)?;
|
||||
e.encode_with(1, ctx)?;
|
||||
e.encode_with(a, ctx)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type TransactionIndex = u32;
|
||||
|
||||
#[derive(
|
||||
Serialize,
|
||||
Deserialize,
|
||||
Encode,
|
||||
Decode,
|
||||
Debug,
|
||||
PartialEq,
|
||||
Eq,
|
||||
PartialOrd,
|
||||
Ord,
|
||||
Clone,
|
||||
std::hash::Hash,
|
||||
)]
|
||||
pub struct TransactionInput {
|
||||
#[n(0)]
|
||||
pub transaction_id: Hash<32>,
|
||||
|
||||
#[n(1)]
|
||||
pub index: u64,
|
||||
}
|
||||
|
||||
pub type UnitInterval = RationalNumber;
|
||||
|
||||
#[derive(Serialize, Deserialize, Encode, Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub struct VrfCert(#[n(0)] pub Bytes, #[n(1)] pub Bytes);
|
||||
|
||||
pub type VrfKeyhash = Hash<32>;
|
||||
|
|
|
|||
353
pallas-primitives/src/plutus_data.rs
Normal file
353
pallas-primitives/src/plutus_data.rs
Normal file
|
|
@ -0,0 +1,353 @@
|
|||
use crate::KeyValuePairs;
|
||||
use pallas_codec::minicbor::{
|
||||
self,
|
||||
data::{IanaTag, Tag},
|
||||
Encode,
|
||||
};
|
||||
use pallas_codec::utils::Int;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt, ops::Deref};
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum PlutusData {
|
||||
Constr(Constr<PlutusData>),
|
||||
Map(KeyValuePairs<PlutusData, PlutusData>),
|
||||
BigInt(BigInt),
|
||||
BoundedBytes(BoundedBytes),
|
||||
Array(Vec<PlutusData>),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for PlutusData {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let type_ = d.datatype()?;
|
||||
|
||||
match type_ {
|
||||
minicbor::data::Type::Tag => {
|
||||
let mut probe = d.probe();
|
||||
let tag = probe.tag()?;
|
||||
|
||||
if tag == IanaTag::PosBignum.tag() || tag == IanaTag::NegBignum.tag() {
|
||||
Ok(Self::BigInt(d.decode_with(ctx)?))
|
||||
} else {
|
||||
match tag.as_u64() {
|
||||
(121..=127) | (1280..=1400) | 102 => Ok(Self::Constr(d.decode_with(ctx)?)),
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"unknown tag for plutus data tag",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => Ok(Self::BigInt(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Map | minicbor::data::Type::MapIndef => {
|
||||
Ok(Self::Map(d.decode_with(ctx)?))
|
||||
}
|
||||
minicbor::data::Type::Bytes => Ok(Self::BoundedBytes(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::BytesIndef => {
|
||||
let mut full = Vec::new();
|
||||
|
||||
for slice in d.bytes_iter()? {
|
||||
full.extend(slice?);
|
||||
}
|
||||
|
||||
Ok(Self::BoundedBytes(BoundedBytes::from(full)))
|
||||
}
|
||||
minicbor::data::Type::Array | minicbor::data::Type::ArrayIndef => {
|
||||
Ok(Self::Array(d.decode_with(ctx)?))
|
||||
}
|
||||
|
||||
any => Err(minicbor::decode::Error::message(format!(
|
||||
"bad cbor data type ({any:?}) for plutus data"
|
||||
))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for PlutusData {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
Self::Constr(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Map(a) => {
|
||||
// we use definite array to match the approach used by haskell's plutus
|
||||
// implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.map(a.len().try_into().unwrap())?;
|
||||
for (k, v) in a.iter() {
|
||||
k.encode(e, ctx)?;
|
||||
v.encode(e, ctx)?;
|
||||
}
|
||||
}
|
||||
Self::BigInt(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::BoundedBytes(a) => {
|
||||
e.encode_with(a, ctx)?;
|
||||
}
|
||||
Self::Array(a) => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L153
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(a, e, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
big_int = int / big_uint / big_nint ; New
|
||||
big_uint = #6.2(bounded_bytes) ; New
|
||||
big_nint = #6.3(bounded_bytes) ; New
|
||||
*/
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub enum BigInt {
|
||||
Int(Int),
|
||||
BigUInt(BoundedBytes),
|
||||
BigNInt(BoundedBytes),
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BigInt {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let datatype = d.datatype()?;
|
||||
|
||||
match datatype {
|
||||
minicbor::data::Type::U8
|
||||
| minicbor::data::Type::U16
|
||||
| minicbor::data::Type::U32
|
||||
| minicbor::data::Type::U64
|
||||
| minicbor::data::Type::I8
|
||||
| minicbor::data::Type::I16
|
||||
| minicbor::data::Type::I32
|
||||
| minicbor::data::Type::I64
|
||||
| minicbor::data::Type::Int => Ok(Self::Int(d.decode_with(ctx)?)),
|
||||
minicbor::data::Type::Tag => {
|
||||
let tag = d.tag()?;
|
||||
if tag == IanaTag::PosBignum.tag() {
|
||||
Ok(Self::BigUInt(d.decode_with(ctx)?))
|
||||
} else if tag == IanaTag::NegBignum.tag() {
|
||||
Ok(Self::BigNInt(d.decode_with(ctx)?))
|
||||
} else {
|
||||
Err(minicbor::decode::Error::message(
|
||||
"invalid cbor tag for big int",
|
||||
))
|
||||
}
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"invalid cbor data type for big int",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> minicbor::encode::Encode<C> for BigInt {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
match self {
|
||||
BigInt::Int(x) => {
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigUInt(x) => {
|
||||
e.tag(IanaTag::PosBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
BigInt::BigNInt(x) => {
|
||||
e.tag(IanaTag::NegBignum)?;
|
||||
e.encode_with(x, ctx)?;
|
||||
}
|
||||
};
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, PartialOrd, Ord, Clone)]
|
||||
pub struct Constr<A> {
|
||||
pub tag: u64,
|
||||
pub any_constructor: Option<u64>,
|
||||
pub fields: Vec<A>,
|
||||
}
|
||||
|
||||
impl<'b, C, A> minicbor::decode::Decode<'b, C> for Constr<A>
|
||||
where
|
||||
A: minicbor::decode::Decode<'b, C>,
|
||||
{
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, ctx: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let tag = d.tag()?;
|
||||
let x = tag.as_u64();
|
||||
match x {
|
||||
121..=127 | 1280..=1400 => Ok(Constr {
|
||||
tag: x,
|
||||
fields: d.decode_with(ctx)?,
|
||||
any_constructor: None,
|
||||
}),
|
||||
102 => {
|
||||
d.array()?;
|
||||
|
||||
Ok(Constr {
|
||||
tag: x,
|
||||
any_constructor: Some(d.decode_with(ctx)?),
|
||||
fields: d.decode_with(ctx)?,
|
||||
})
|
||||
}
|
||||
_ => Err(minicbor::decode::Error::message(
|
||||
"bad tag code for plutus data",
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, A> minicbor::encode::Encode<C> for Constr<A>
|
||||
where
|
||||
A: minicbor::encode::Encode<C>,
|
||||
{
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
e.tag(Tag::new(self.tag))?;
|
||||
|
||||
match self.tag {
|
||||
102 => {
|
||||
// definite length array here
|
||||
// https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L152
|
||||
e.array(2)?;
|
||||
e.encode_with(self.any_constructor.unwrap_or_default(), ctx)?;
|
||||
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation https://github.com/input-output-hk/plutus/blob/9538fc9829426b2ecb0628d352e2d7af96ec8204/plutus-core/plutus-core/src/PlutusCore/Data.hs#L144
|
||||
// default encoder for a list:
|
||||
// https://github.com/well-typed/cborg/blob/4bdc818a1f0b35f38bc118a87944630043b58384/serialise/src/Codec/Serialise/Class.hs#L181
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
_ => {
|
||||
// we use definite array for empty array or indef array otherwise to match
|
||||
// haskell implementation. See above reference.
|
||||
encode_list(&self.fields, e, ctx)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Defined to encode PlutusData bytestring as it is done in the canonical
|
||||
/// plutus implementation
|
||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||
#[serde(into = "String")]
|
||||
#[serde(try_from = "String")]
|
||||
pub struct BoundedBytes(Vec<u8>);
|
||||
|
||||
impl From<Vec<u8>> for BoundedBytes {
|
||||
fn from(xs: Vec<u8>) -> Self {
|
||||
BoundedBytes(xs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for Vec<u8> {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
b.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for BoundedBytes {
|
||||
type Target = Vec<u8>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<String> for BoundedBytes {
|
||||
type Error = hex::FromHexError;
|
||||
|
||||
fn try_from(value: String) -> Result<Self, Self::Error> {
|
||||
let v = hex::decode(value)?;
|
||||
Ok(BoundedBytes(v))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<BoundedBytes> for String {
|
||||
fn from(b: BoundedBytes) -> Self {
|
||||
hex::encode(b.deref())
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for BoundedBytes {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let bytes: Vec<u8> = self.clone().into();
|
||||
|
||||
f.write_str(&hex::encode(bytes))
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> Encode<C> for BoundedBytes {
|
||||
fn encode<W: minicbor::encode::Write>(
|
||||
&self,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
_: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// we match the haskell implementation by encoding bytestrings longer than 64
|
||||
// bytes as indefinite lists of bytes
|
||||
const CHUNK_SIZE: usize = 64;
|
||||
let bs: &Vec<u8> = self.deref();
|
||||
if bs.len() <= 64 {
|
||||
e.bytes(bs)?;
|
||||
} else {
|
||||
e.begin_bytes()?;
|
||||
for b in bs.chunks(CHUNK_SIZE) {
|
||||
e.bytes(b)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b, C> minicbor::decode::Decode<'b, C> for BoundedBytes {
|
||||
fn decode(d: &mut minicbor::Decoder<'b>, _: &mut C) -> Result<Self, minicbor::decode::Error> {
|
||||
let mut res = Vec::new();
|
||||
for chunk in d.bytes_iter()? {
|
||||
let bs = chunk?;
|
||||
res.extend_from_slice(bs);
|
||||
}
|
||||
Ok(BoundedBytes::from(res))
|
||||
}
|
||||
}
|
||||
|
||||
fn encode_list<C, W: minicbor::encode::Write, A: minicbor::encode::Encode<C>>(
|
||||
a: &Vec<A>,
|
||||
e: &mut minicbor::Encoder<W>,
|
||||
ctx: &mut C,
|
||||
) -> Result<(), minicbor::encode::Error<W::Error>> {
|
||||
// Mimics default haskell list encoding from cborg:
|
||||
// We use indef array for non-empty arrays but definite 0-length array for empty
|
||||
if a.is_empty() {
|
||||
e.array(0)?;
|
||||
} else {
|
||||
e.begin_array()?;
|
||||
for v in a {
|
||||
e.encode_with(v, ctx)?;
|
||||
}
|
||||
e.end()?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -5,7 +5,7 @@ use pallas_primitives::alonzo;
|
|||
use crate::MultiEraTx;
|
||||
|
||||
impl<'b> MultiEraTx<'b> {
|
||||
pub fn aux_plutus_v1_scripts(&self) -> &[alonzo::PlutusScript] {
|
||||
pub fn aux_plutus_v1_scripts(&self) -> &[alonzo::PlutusScript<1>] {
|
||||
if let Some(aux_data) = self.aux_data() {
|
||||
if let alonzo::AuxiliaryData::PostAlonzo(x) = aux_data.deref() {
|
||||
if let Some(plutus) = &x.plutus_scripts {
|
||||
|
|
|
|||
|
|
@ -82,9 +82,9 @@ impl OriginalHash<28> for KeepRaw<'_, alonzo::NativeScript> {
|
|||
}
|
||||
}
|
||||
|
||||
impl ComputeHash<28> for alonzo::PlutusScript {
|
||||
impl<const VERSION: usize> ComputeHash<28> for alonzo::PlutusScript<VERSION> {
|
||||
fn compute_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged(&self.0, 1)
|
||||
Hasher::<224>::hash_tagged(&self.0, VERSION as u8)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -124,12 +124,6 @@ impl OriginalHash<32> for KeepRaw<'_, babbage::Header> {
|
|||
}
|
||||
}
|
||||
|
||||
impl ComputeHash<28> for babbage::PlutusV2Script {
|
||||
fn compute_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged(&self.0, 2)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeHash<32> for babbage::TransactionBody {
|
||||
fn compute_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
|
|
@ -159,12 +153,6 @@ impl ComputeHash<32> for babbage::DatumOption {
|
|||
|
||||
// conway
|
||||
|
||||
impl ComputeHash<28> for conway::PlutusV3Script {
|
||||
fn compute_hash(&self) -> Hash<28> {
|
||||
Hasher::<224>::hash_tagged(&self.0, 3)
|
||||
}
|
||||
}
|
||||
|
||||
impl ComputeHash<32> for conway::TransactionBody {
|
||||
fn compute_hash(&self) -> Hash<32> {
|
||||
Hasher::<256>::hash_cbor(self)
|
||||
|
|
@ -334,7 +322,7 @@ mod tests {
|
|||
fn plutus_v1_script_hashes_as_cardano_cli() {
|
||||
let bytecode_hex = include_str!("../../test_data/jpgstore.plutus");
|
||||
let bytecode = hex::decode(bytecode_hex).unwrap();
|
||||
let script = alonzo::PlutusScript(Bytes::from(bytecode));
|
||||
let script = alonzo::PlutusScript::<1>(Bytes::from(bytecode));
|
||||
|
||||
let generated = script.compute_hash().to_string();
|
||||
|
||||
|
|
@ -350,7 +338,7 @@ mod tests {
|
|||
fn plutus_v2_script_hashes_as_cardano_cli() {
|
||||
let bytecode_hex = include_str!("../../test_data/v2script.plutus");
|
||||
let bytecode = hex::decode(bytecode_hex).unwrap();
|
||||
let script = babbage::PlutusV2Script(Bytes::from(bytecode));
|
||||
let script = babbage::PlutusScript::<2>(Bytes::from(bytecode));
|
||||
|
||||
let generated = script.compute_hash().to_string();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
//! Lightweight inspection of block data without full CBOR decoding
|
||||
|
||||
use pallas_codec::minicbor::decode::{Token, Tokenizer};
|
||||
use pallas_codec::minicbor::{data::Token, decode::Tokenizer};
|
||||
|
||||
use crate::Era;
|
||||
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ pub type UnitInterval = alonzo::UnitInterval;
|
|||
pub type Nonce = alonzo::Nonce;
|
||||
pub type ExUnitPrices = alonzo::ExUnitPrices;
|
||||
pub type ExUnits = alonzo::ExUnits;
|
||||
pub type AlonzoCostMdls = alonzo::CostMdls;
|
||||
pub type BabbageCostMdls = babbage::CostMdls;
|
||||
pub type ConwayCostMdls = conway::CostMdls;
|
||||
pub type AlonzoCostModels = alonzo::CostModels;
|
||||
pub type BabbageCostModels = babbage::CostModels;
|
||||
pub type ConwayCostModels = conway::CostModels;
|
||||
pub type ProtocolVersion = alonzo::ProtocolVersion;
|
||||
pub type PoolVotingThresholds = conway::PoolVotingThresholds;
|
||||
pub type DRepVotingThresholds = conway::DRepVotingThresholds;
|
||||
|
|
@ -157,7 +157,9 @@ impl<'b> MultiEraUpdate<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn alonzo_first_proposed_cost_models_for_script_languages(&self) -> Option<AlonzoCostMdls> {
|
||||
pub fn alonzo_first_proposed_cost_models_for_script_languages(
|
||||
&self,
|
||||
) -> Option<AlonzoCostModels> {
|
||||
match self {
|
||||
MultiEraUpdate::AlonzoCompatible(x) => x
|
||||
.proposed_protocol_parameter_updates
|
||||
|
|
@ -169,7 +171,7 @@ impl<'b> MultiEraUpdate<'b> {
|
|||
|
||||
pub fn babbage_first_proposed_cost_models_for_script_languages(
|
||||
&self,
|
||||
) -> Option<BabbageCostMdls> {
|
||||
) -> Option<BabbageCostModels> {
|
||||
match self {
|
||||
MultiEraUpdate::Babbage(x) => x
|
||||
.proposed_protocol_parameter_updates
|
||||
|
|
@ -179,7 +181,9 @@ impl<'b> MultiEraUpdate<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn conway_first_proposed_cost_models_for_script_languages(&self) -> Option<ConwayCostMdls> {
|
||||
pub fn conway_first_proposed_cost_models_for_script_languages(
|
||||
&self,
|
||||
) -> Option<ConwayCostModels> {
|
||||
match self {
|
||||
MultiEraUpdate::Conway(x) => x
|
||||
.proposed_protocol_parameter_updates
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use pallas_codec::utils::KeepRaw;
|
||||
use pallas_primitives::{
|
||||
alonzo::{self, BootstrapWitness, NativeScript, PlutusData, VKeyWitness},
|
||||
babbage::PlutusV2Script,
|
||||
conway::PlutusV3Script,
|
||||
alonzo::{self, BootstrapWitness, NativeScript, VKeyWitness},
|
||||
PlutusData, PlutusScript,
|
||||
};
|
||||
|
||||
use crate::{MultiEraRedeemer, MultiEraTx};
|
||||
|
|
@ -80,7 +79,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn plutus_v1_scripts(&self) -> &[alonzo::PlutusScript] {
|
||||
pub fn plutus_v1_scripts(&self) -> &[alonzo::PlutusScript<1>] {
|
||||
match self {
|
||||
Self::Byron(_) => &[],
|
||||
Self::AlonzoCompatible(x, _) => x
|
||||
|
|
@ -181,7 +180,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
})
|
||||
}
|
||||
|
||||
pub fn plutus_v2_scripts(&self) -> &[PlutusV2Script] {
|
||||
pub fn plutus_v2_scripts(&self) -> &[PlutusScript<2>] {
|
||||
match self {
|
||||
Self::Byron(_) => &[],
|
||||
Self::AlonzoCompatible(_, _) => &[],
|
||||
|
|
@ -200,7 +199,7 @@ impl<'b> MultiEraTx<'b> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn plutus_v3_scripts(&self) -> &[PlutusV3Script] {
|
||||
pub fn plutus_v3_scripts(&self) -> &[PlutusScript<3>] {
|
||||
match self {
|
||||
Self::Byron(_) => &[],
|
||||
Self::AlonzoCompatible(_, _) => &[],
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ use pallas_codec::utils::{CborWrap, KeyValuePairs};
|
|||
use pallas_crypto::hash::Hash;
|
||||
use pallas_primitives::{
|
||||
babbage::{
|
||||
DatumOption, ExUnits as PallasExUnits, NativeScript, NetworkId, PlutusData, PlutusV1Script,
|
||||
PlutusV2Script, PostAlonzoTransactionOutput, PseudoScript as PallasScript,
|
||||
PseudoTransactionOutput, Redeemer, RedeemerTag, TransactionBody, TransactionInput,
|
||||
Tx as BabbageTx, Value, WitnessSet,
|
||||
DatumOption, ExUnits as PallasExUnits, NativeScript, NetworkId, PlutusData, PlutusScript,
|
||||
PostAlonzoTransactionOutput, PseudoScript as PallasScript, PseudoTransactionOutput,
|
||||
Redeemer, RedeemerTag, TransactionBody, TransactionInput, Tx as BabbageTx, Value,
|
||||
WitnessSet,
|
||||
},
|
||||
Fragment,
|
||||
};
|
||||
|
|
@ -88,10 +88,9 @@ impl BuildBabbage for StagingTransaction {
|
|||
.collect();
|
||||
|
||||
let network_id = if let Some(nid) = self.network_id {
|
||||
match nid {
|
||||
0 => Some(NetworkId::One),
|
||||
1 => Some(NetworkId::Two),
|
||||
_ => return Err(TxBuilderError::InvalidNetworkId),
|
||||
match NetworkId::try_from(nid) {
|
||||
Err(()) => return Err(TxBuilderError::InvalidNetworkId),
|
||||
Ok(network_id) => Some(network_id),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
|
|
@ -125,12 +124,12 @@ impl BuildBabbage for StagingTransaction {
|
|||
native_script.push(script)
|
||||
}
|
||||
ScriptKind::PlutusV1 => {
|
||||
let script = PlutusV1Script(script.bytes.into());
|
||||
let script = PlutusScript::<1>(script.bytes.into());
|
||||
|
||||
plutus_v1_script.push(script)
|
||||
}
|
||||
ScriptKind::PlutusV2 => {
|
||||
let script = PlutusV2Script(script.bytes.into());
|
||||
let script = PlutusScript::<2>(script.bytes.into());
|
||||
|
||||
plutus_v2_script.push(script)
|
||||
}
|
||||
|
|
@ -313,12 +312,12 @@ impl Output {
|
|||
NativeScript::decode_fragment(s.bytes.as_ref())
|
||||
.map_err(|_| TxBuilderError::MalformedScript)?,
|
||||
),
|
||||
ScriptKind::PlutusV1 => {
|
||||
PallasScript::PlutusV1Script(PlutusV1Script(s.bytes.as_ref().to_vec().into()))
|
||||
}
|
||||
ScriptKind::PlutusV2 => {
|
||||
PallasScript::PlutusV2Script(PlutusV2Script(s.bytes.as_ref().to_vec().into()))
|
||||
}
|
||||
ScriptKind::PlutusV1 => PallasScript::PlutusV1Script(PlutusScript::<1>(
|
||||
s.bytes.as_ref().to_vec().into(),
|
||||
)),
|
||||
ScriptKind::PlutusV2 => PallasScript::PlutusV2Script(PlutusScript::<2>(
|
||||
s.bytes.as_ref().to_vec().into(),
|
||||
)),
|
||||
};
|
||||
|
||||
Some(CborWrap(script))
|
||||
|
|
|
|||
|
|
@ -185,7 +185,7 @@ impl<C: LedgerContext> Mapper<C> {
|
|||
babbage::StakeCredential::AddrKeyhash(x) => {
|
||||
u5c::stake_credential::StakeCredential::AddrKeyHash(x.to_vec().into())
|
||||
}
|
||||
babbage::StakeCredential::Scripthash(x) => {
|
||||
babbage::StakeCredential::ScriptHash(x) => {
|
||||
u5c::stake_credential::StakeCredential::ScriptHash(x.to_vec().into())
|
||||
}
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue